summaryrefslogtreecommitdiffstats
path: root/source/slang/type-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/type-layout.cpp')
-rw-r--r--source/slang/type-layout.cpp180
1 files changed, 115 insertions, 65 deletions
diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp
index 822311f60..9f2aee922 100644
--- a/source/slang/type-layout.cpp
+++ b/source/slang/type-layout.cpp
@@ -427,6 +427,7 @@ struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
virtual LayoutRulesImpl* getVaryingOutputRules() override;
virtual LayoutRulesImpl* getSpecializationConstantRules() override;
virtual LayoutRulesImpl* getShaderStorageBufferRules() override;
+ virtual LayoutRulesImpl* getParameterBlockRules() override;
virtual MatrixLayoutMode getDefaultMatrixLayoutMode() override
{
@@ -457,6 +458,7 @@ struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
virtual LayoutRulesImpl* getVaryingOutputRules() override;
virtual LayoutRulesImpl* getSpecializationConstantRules() override;
virtual LayoutRulesImpl* getShaderStorageBufferRules() override;
+ virtual LayoutRulesImpl* getParameterBlockRules() override;
virtual MatrixLayoutMode getDefaultMatrixLayoutMode() override
{
@@ -519,6 +521,12 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules()
return &kStd140LayoutRulesImpl_;
}
+LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getParameterBlockRules()
+{
+ // TODO: actually pick something appropriate
+ return &kStd140LayoutRulesImpl_;
+}
+
LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getPushConstantBufferRules()
{
return &kGLSLPushConstantLayoutRulesImpl_;
@@ -556,6 +564,13 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules()
return &kHLSLConstantBufferLayoutRulesImpl_;
}
+LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getParameterBlockRules()
+{
+ // TODO: actually pick something appropriate...
+ return &kHLSLConstantBufferLayoutRulesImpl_;
+}
+
+
LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getPushConstantBufferRules()
{
return &kHLSLConstantBufferLayoutRulesImpl_;
@@ -685,8 +700,8 @@ SimpleLayoutInfo GetSimpleLayoutImpl(
return info;
}
-static SimpleLayoutInfo getParameterBlockLayoutInfo(
- RefPtr<ParameterBlockType> type,
+static SimpleLayoutInfo getParameterGroupLayoutInfo(
+ RefPtr<ParameterGroupType> type,
LayoutRulesImpl* rules)
{
if( type->As<ConstantBufferType>() )
@@ -701,14 +716,22 @@ static SimpleLayoutInfo getParameterBlockLayoutInfo(
{
return rules->GetObjectLayout(ShaderParameterKind::ShaderStorageBuffer);
}
+ else if (type->As<ParameterBlockType>())
+ {
+ // TODO(tfoley): Should a parameter block *always* consume at least
+ // one `set`/`space`, or should we hold back and just allocate this
+ // if it actually contains anything?
+ return SimpleLayoutInfo(LayoutResourceKind::ParameterBlock, 1);
+ }
+
// TODO: the vertex-input and fragment-output cases should
// only actually apply when we are at the appropriate stage in
// the pipeline...
- else if( type->As<GLSLInputParameterBlockType>() )
+ else if( type->As<GLSLInputParameterGroupType>() )
{
return SimpleLayoutInfo(LayoutResourceKind::VertexInput, 0);
}
- else if( type->As<GLSLOutputParameterBlockType>() )
+ else if( type->As<GLSLOutputParameterGroupType>() )
{
return SimpleLayoutInfo(LayoutResourceKind::FragmentOutput, 0);
}
@@ -736,19 +759,19 @@ RefPtr<TypeLayout> createTypeLayout(
Type* type,
SimpleLayoutInfo offset);
-RefPtr<ParameterBlockTypeLayout>
-createParameterBlockTypeLayout(
+RefPtr<ParameterGroupTypeLayout>
+createParameterGroupTypeLayout(
TypeLayoutContext* context,
- RefPtr<ParameterBlockType> parameterBlockType,
- SimpleLayoutInfo parameterBlockInfo,
+ RefPtr<ParameterGroupType> parameterGroupType,
+ SimpleLayoutInfo parameterGroupInfo,
RefPtr<TypeLayout> elementTypeLayout)
{
- auto parameterBlockRules = context->rules;
+ auto parameterGroupRules = context->rules;
- auto typeLayout = new ParameterBlockTypeLayout();
+ auto typeLayout = new ParameterGroupTypeLayout();
- typeLayout->type = parameterBlockType;
- typeLayout->rules = parameterBlockRules;
+ typeLayout->type = parameterGroupType;
+ typeLayout->rules = parameterGroupRules;
typeLayout->elementTypeLayout = elementTypeLayout;
@@ -757,7 +780,7 @@ createParameterBlockTypeLayout(
// originally (which should be a single binding "slot"
// and hence no uniform data).
//
- typeLayout->uniformAlignment = parameterBlockInfo.alignment;
+ typeLayout->uniformAlignment = parameterGroupInfo.alignment;
SLANG_RELEASE_ASSERT(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform));
SLANG_RELEASE_ASSERT(typeLayout->uniformAlignment == 1);
@@ -771,73 +794,96 @@ createParameterBlockTypeLayout(
// Make sure that we allocate resource usage for the
// parameter block itself.
- if( parameterBlockInfo.size )
+ if( parameterGroupInfo.size )
{
typeLayout->addResourceUsage(
- parameterBlockInfo.kind,
- parameterBlockInfo.size);
+ parameterGroupInfo.kind,
+ parameterGroupInfo.size);
}
- // Now, if the element type itself had any resources, then
- // we need to make these part of the layout for our block
+ // The layout rules for a constant buffer, vs. a "parameter block"
+ // are different, with respect to how they expose layout information
+ // for underlying resources.
//
- // TODO: re-consider this decision, since it creates
- // complications...
- for( auto elementResourceInfo : elementTypeLayout->resourceInfos )
+ // A parameter block should *not* expose the fine-grained resource
+ // prameters it contains, and should only expose a total number
+ // of `space`s or `set`s that it consumes.
+ if (parameterGroupInfo.kind == LayoutResourceKind::ParameterBlock)
{
- // Skip uniform data, since that is encapsualted behind the constant buffer
- if(elementResourceInfo.kind == LayoutResourceKind::Uniform)
- break;
+ // Iterate over element types, but *only* accumulate usage
+ // info for types that consume whole register sets/spaces.
+ for( auto elementResourceInfo : elementTypeLayout->resourceInfos )
+ {
+ if(elementResourceInfo.kind != LayoutResourceKind::ParameterBlock)
+ break;
+
+ typeLayout->addResourceUsage(elementResourceInfo);
+ }
+ }
+ else
+ {
+ // In the ordinary case (e.g., a constant buffer) then we need
+ // to make sure that any resources nested in the element type
+ // get counted against the container type, so that we can
+ // allocate registers to it directly.
+ for( auto elementResourceInfo : elementTypeLayout->resourceInfos )
+ {
+ // Skip uniform data, since that is encapsualted behind the constant buffer
+ if(elementResourceInfo.kind == LayoutResourceKind::Uniform)
+ break;
- typeLayout->addResourceUsage(elementResourceInfo);
+ typeLayout->addResourceUsage(elementResourceInfo);
+ }
}
+
+
return typeLayout;
}
-RefPtr<ParameterBlockTypeLayout>
-createParameterBlockTypeLayout(
- RefPtr<ParameterBlockType> parameterBlockType,
- LayoutRulesImpl* parameterBlockRules,
- SimpleLayoutInfo parameterBlockInfo,
+RefPtr<ParameterGroupTypeLayout>
+createParameterGroupTypeLayout(
+ RefPtr<ParameterGroupType> parameterGroupType,
+ LayoutRulesImpl* parameterGroupRules,
+ SimpleLayoutInfo parameterGroupInfo,
RefPtr<TypeLayout> elementTypeLayout)
{
TypeLayoutContext context;
- context.rules = parameterBlockRules;
- context.matrixLayoutMode = parameterBlockRules->getDefaultMatrixLayoutMode();
+ context.rules = parameterGroupRules;
+ context.matrixLayoutMode = parameterGroupRules->getDefaultMatrixLayoutMode();
- return createParameterBlockTypeLayout(
+ return createParameterGroupTypeLayout(
&context,
- parameterBlockType,
- parameterBlockInfo,
+ parameterGroupType,
+ parameterGroupInfo,
elementTypeLayout);
}
-RefPtr<ParameterBlockTypeLayout>
-createParameterBlockTypeLayout(
+RefPtr<ParameterGroupTypeLayout>
+createParameterGroupTypeLayout(
TypeLayoutContext* context,
- RefPtr<ParameterBlockType> parameterBlockType,
+ RefPtr<ParameterGroupType> parameterGroupType,
RefPtr<Type> elementType,
LayoutRulesImpl* elementTypeRules)
{
- auto parameterBlockRules = context->rules;
+ auto parameterGroupRules = context->rules;
// First compute resource usage of the block itself.
// For now we assume that the layout of the block can
// always be described in a `SimpleLayoutInfo` (only
// a single resource kind consumed).
SimpleLayoutInfo info;
- if (parameterBlockType)
+ if (parameterGroupType)
{
- info = getParameterBlockLayoutInfo(
- parameterBlockType,
- parameterBlockRules);
+ info = getParameterGroupLayoutInfo(
+ parameterGroupType,
+ parameterGroupRules);
}
else
{
// If there is no concrete type, then it seems like we are
// being asked to compute layout for the global scope
- info = parameterBlockRules->GetObjectLayout(ShaderParameterKind::ConstantBuffer);
+ info = parameterGroupRules->GetObjectLayout(ShaderParameterKind::ConstantBuffer);
}
// Now compute a layout for the elements of the parameter block.
@@ -852,37 +898,41 @@ createParameterBlockTypeLayout(
elementType,
info);
- return createParameterBlockTypeLayout(
+ return createParameterGroupTypeLayout(
context,
- parameterBlockType,
+ parameterGroupType,
info,
elementTypeLayout);
}
LayoutRulesImpl* getParameterBufferElementTypeLayoutRules(
- RefPtr<ParameterBlockType> parameterBlockType,
+ RefPtr<ParameterGroupType> parameterGroupType,
LayoutRulesImpl* rules)
{
- if( parameterBlockType->As<ConstantBufferType>() )
+ if( parameterGroupType->As<ConstantBufferType>() )
{
return rules->getLayoutRulesFamily()->getConstantBufferRules();
}
- else if( parameterBlockType->As<TextureBufferType>() )
+ else if( parameterGroupType->As<TextureBufferType>() )
{
return rules->getLayoutRulesFamily()->getTextureBufferRules();
}
- else if( parameterBlockType->As<GLSLInputParameterBlockType>() )
+ else if( parameterGroupType->As<GLSLInputParameterGroupType>() )
{
return rules->getLayoutRulesFamily()->getVaryingInputRules();
}
- else if( parameterBlockType->As<GLSLOutputParameterBlockType>() )
+ else if( parameterGroupType->As<GLSLOutputParameterGroupType>() )
{
return rules->getLayoutRulesFamily()->getVaryingOutputRules();
}
- else if( parameterBlockType->As<GLSLShaderStorageBufferType>() )
+ else if( parameterGroupType->As<GLSLShaderStorageBufferType>() )
{
return rules->getLayoutRulesFamily()->getShaderStorageBufferRules();
}
+ else if (parameterGroupType->As<ParameterBlockType>())
+ {
+ return rules->getLayoutRulesFamily()->getParameterBlockRules();
+ }
else
{
SLANG_UNEXPECTED("uhandled parameter block type");
@@ -890,23 +940,23 @@ LayoutRulesImpl* getParameterBufferElementTypeLayoutRules(
}
}
-RefPtr<ParameterBlockTypeLayout>
-createParameterBlockTypeLayout(
+RefPtr<ParameterGroupTypeLayout>
+createParameterGroupTypeLayout(
TypeLayoutContext* context,
- RefPtr<ParameterBlockType> parameterBlockType)
+ RefPtr<ParameterGroupType> parameterGroupType)
{
- auto parameterBlockRules = context->rules;
+ auto parameterGroupRules = context->rules;
// Determine the layout rules to use for the contents of the block
auto elementTypeRules = getParameterBufferElementTypeLayoutRules(
- parameterBlockType,
- parameterBlockRules);
+ parameterGroupType,
+ parameterGroupRules);
- auto elementType = parameterBlockType->elementType;
+ auto elementType = parameterGroupType->elementType;
- return createParameterBlockTypeLayout(
+ return createParameterGroupTypeLayout(
context,
- parameterBlockType,
+ parameterGroupType,
elementType,
elementTypeRules);
}
@@ -1015,14 +1065,14 @@ SimpleLayoutInfo GetLayoutImpl(
{
auto rules = context->rules;
- if (auto parameterBlockType = type->As<ParameterBlockType>())
+ if (auto parameterGroupType = type->As<ParameterGroupType>())
{
// If the user is just interested in uniform layout info,
// then this is easy: a `ConstantBuffer<T>` is really no
// different from a `Texture2D<U>` in terms of how it
// should be handled as a member of a container.
//
- auto info = getParameterBlockLayoutInfo(parameterBlockType, rules);
+ auto info = getParameterGroupLayoutInfo(parameterGroupType, rules);
// The more interesting case, though, is when the user
// is requesting us to actually create a `TypeLayout`,
@@ -1037,9 +1087,9 @@ SimpleLayoutInfo GetLayoutImpl(
//
if (outTypeLayout)
{
- *outTypeLayout = createParameterBlockTypeLayout(
+ *outTypeLayout = createParameterGroupTypeLayout(
context,
- parameterBlockType);
+ parameterGroupType);
}
return info;