diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2017-07-14 12:07:45 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-14 12:07:45 -0700 |
| commit | ffa7f2a9e919be6f155d1c6e62e85827ffc6e3bd (patch) | |
| tree | fb6ab85174f2f630dd49910bc69bb23309f9eee0 /source/slang/type-layout.cpp | |
| parent | d9366db8993c566fbb0af780c13db438dbf74022 (diff) | |
| parent | f4ac13d6718d6433f69eb21311110c8225a95aee (diff) | |
Merge pull request #90 from tfoleyNV/cbuffer-field-layout-fix
Adjust type layout when parameter block constains member using the sa…
Diffstat (limited to 'source/slang/type-layout.cpp')
| -rw-r--r-- | source/slang/type-layout.cpp | 121 |
1 files changed, 88 insertions, 33 deletions
diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp index 2e0f3035a..6ca2d68fb 100644 --- a/source/slang/type-layout.cpp +++ b/source/slang/type-layout.cpp @@ -681,28 +681,14 @@ static SimpleLayoutInfo getParameterBlockLayoutInfo( RefPtr<ParameterBlockTypeLayout> createParameterBlockTypeLayout( RefPtr<ParameterBlockType> parameterBlockType, - RefPtr<TypeLayout> elementTypeLayout, - LayoutRulesImpl* rules) + LayoutRulesImpl* parameterBlockRules, + SimpleLayoutInfo parameterBlockInfo, + RefPtr<TypeLayout> elementTypeLayout) { - SimpleLayoutInfo info; - if (parameterBlockType) - { - info = getParameterBlockLayoutInfo( - parameterBlockType, - rules); - } - else - { - // If there is no concrete type, then it seems like we are - // being asked to compute layout for the global scope - info = rules->GetObjectLayout(ShaderParameterKind::ConstantBuffer); - } - - auto typeLayout = new ParameterBlockTypeLayout(); typeLayout->type = parameterBlockType; - typeLayout->rules = rules; + typeLayout->rules = parameterBlockRules; typeLayout->elementTypeLayout = elementTypeLayout; @@ -711,7 +697,7 @@ createParameterBlockTypeLayout( // originally (which should be a single binding "slot" // and hence no uniform data). // - typeLayout->uniformAlignment = info.alignment; + typeLayout->uniformAlignment = parameterBlockInfo.alignment; assert(!typeLayout->FindResourceInfo(LayoutResourceKind::Uniform)); assert(typeLayout->uniformAlignment == 1); @@ -725,11 +711,11 @@ createParameterBlockTypeLayout( // Make sure that we allocate resource usage for the // parameter block itself. - if( info.size ) + if( parameterBlockInfo.size ) { typeLayout->addResourceUsage( - info.kind, - info.size); + parameterBlockInfo.kind, + parameterBlockInfo.size); } // Now, if the element type itself had any resources, then @@ -749,6 +735,48 @@ createParameterBlockTypeLayout( return typeLayout; } +RefPtr<ParameterBlockTypeLayout> +createParameterBlockTypeLayout( + RefPtr<ParameterBlockType> parameterBlockType, + LayoutRulesImpl* parameterBlockRules, + RefPtr<ExpressionType> elementType, + LayoutRulesImpl* elementTypeRules) +{ + // 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) + { + info = getParameterBlockLayoutInfo( + parameterBlockType, + parameterBlockRules); + } + 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); + } + + // Now compute a layout for the elements of the parameter block. + // Note that we need to be careful and deal with the case where + // the elements of the block use the same resource kind consumed + // by the block itself. + + auto elementTypeLayout = CreateTypeLayout( + elementType, + elementTypeRules, + info); + + return createParameterBlockTypeLayout( + parameterBlockType, + parameterBlockRules, + info, + elementTypeLayout); +} + LayoutRulesImpl* getParameterBufferElementTypeLayoutRules( RefPtr<ParameterBlockType> parameterBlockType, LayoutRulesImpl* rules) @@ -783,22 +811,20 @@ LayoutRulesImpl* getParameterBufferElementTypeLayoutRules( RefPtr<ParameterBlockTypeLayout> createParameterBlockTypeLayout( RefPtr<ParameterBlockType> parameterBlockType, - LayoutRulesImpl* rules) + LayoutRulesImpl* parameterBlockRules) { // Determine the layout rules to use for the contents of the block - auto parameterBlockLayoutRules = getParameterBufferElementTypeLayoutRules( + auto elementTypeRules = getParameterBufferElementTypeLayoutRules( parameterBlockType, - rules); + parameterBlockRules); - // Create and save type layout for the buffer contents. - auto elementTypeLayout = CreateTypeLayout( - parameterBlockType->elementType.Ptr(), - parameterBlockLayoutRules); + auto elementType = parameterBlockType->elementType; return createParameterBlockTypeLayout( parameterBlockType, - elementTypeLayout, - rules); + parameterBlockRules, + elementType, + elementTypeRules); } // Create a type layout for a structured buffer type. @@ -863,8 +889,23 @@ createStructuredBufferTypeLayout( SimpleLayoutInfo GetLayoutImpl( ExpressionType* type, LayoutRulesImpl* rules, + RefPtr<TypeLayout>* outTypeLayout, + SimpleLayoutInfo offset); + +SimpleLayoutInfo GetLayoutImpl( + ExpressionType* type, + LayoutRulesImpl* rules, RefPtr<TypeLayout>* outTypeLayout) { + return GetLayoutImpl(type, rules, outTypeLayout, SimpleLayoutInfo()); +} + +SimpleLayoutInfo GetLayoutImpl( + ExpressionType* type, + LayoutRulesImpl* rules, + RefPtr<TypeLayout>* outTypeLayout, + SimpleLayoutInfo offset) +{ if (auto parameterBlockType = type->As<ParameterBlockType>()) { // If the user is just interested in uniform layout info, @@ -1184,6 +1225,15 @@ SimpleLayoutInfo GetLayoutImpl( fieldResourceInfo->index = structTypeResourceInfo->count; structTypeResourceInfo->count += fieldTypeResourceInfo.count; } + + // If the user passed in offset info, then apply it here + if (offset.size) + { + if (auto fieldResInfo = fieldLayout->FindResourceInfo(offset.kind)) + { + fieldResInfo->index += offset.size; + } + } } } @@ -1226,13 +1276,18 @@ SimpleLayoutInfo GetLayout(ExpressionType* inType, LayoutRulesImpl* rules) return GetLayoutImpl(inType, rules, nullptr); } -RefPtr<TypeLayout> CreateTypeLayout(ExpressionType* type, LayoutRulesImpl* rules) +RefPtr<TypeLayout> CreateTypeLayout(ExpressionType* type, LayoutRulesImpl* rules, SimpleLayoutInfo offset) { RefPtr<TypeLayout> typeLayout; - GetLayoutImpl(type, rules, &typeLayout); + GetLayoutImpl(type, rules, &typeLayout, offset); return typeLayout; } +RefPtr<TypeLayout> CreateTypeLayout(ExpressionType* type, LayoutRulesImpl* rules) +{ + return CreateTypeLayout(type, rules, SimpleLayoutInfo()); +} + SimpleLayoutInfo GetLayout(ExpressionType* type, LayoutRule rule) { LayoutRulesImpl* rulesImpl = GetLayoutRulesImpl(rule); |
