diff options
Diffstat (limited to 'source/slang/type-layout.cpp')
| -rw-r--r-- | source/slang/type-layout.cpp | 180 |
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; |
