diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 353 | ||||
| -rw-r--r-- | source/slang/reflection.cpp | 6 | ||||
| -rw-r--r-- | source/slang/type-layout.cpp | 21 | ||||
| -rw-r--r-- | source/slang/type-layout.h | 8 |
4 files changed, 250 insertions, 138 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 33fd46bdb..bf7ad0c3a 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -3451,21 +3451,79 @@ struct EmitVisitor EmitVarDeclCommon(DeclRef<Decl>(decl.Ptr(), nullptr).As<VarDeclBase>()); } + // A chain of variables to use for emitting semantic/layout info + struct EmitVarChain + { + VarLayout* varLayout; + EmitVarChain* next; + + EmitVarChain() + : varLayout(0) + , next(0) + {} + + EmitVarChain(VarLayout* varLayout) + : varLayout(varLayout) + , next(0) + {} + + EmitVarChain(VarLayout* varLayout, EmitVarChain* next) + : varLayout(varLayout) + , next(next) + {} + }; + + UInt getBindingOffset(EmitVarChain* chain, LayoutResourceKind kind) + { + UInt offset = 0; + for(auto cc = chain; cc; cc = cc->next) + { + if(auto resInfo = cc->varLayout->FindResourceInfo(kind)) + { + offset += resInfo->index; + } + } + return offset; + } + + UInt getBindingSpace(EmitVarChain* chain, LayoutResourceKind kind) + { + UInt space = 0; + for(auto cc = chain; cc; cc = cc->next) + { + auto varLayout = cc->varLayout; + if(auto resInfo = varLayout->FindResourceInfo(kind)) + { + space += resInfo->space; + } + if(auto resInfo = varLayout->FindResourceInfo(LayoutResourceKind::RegisterSpace)) + { + space += resInfo->index; + } + } + return space; + } + // Emit a single `regsiter` semantic, as appropriate for a given resource-type-specific layout info void emitHLSLRegisterSemantic( - VarLayout::ResourceInfo const& info, - UInt spaceOffset, - + LayoutResourceKind kind, + EmitVarChain* chain, // Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`) char const* uniformSemanticSpelling = "register") { - UInt space = info.space + spaceOffset; + if(!chain) + return; + if(!chain->varLayout->FindResourceInfo(kind)) + return; - switch(info.kind) + UInt index = getBindingOffset(chain, kind); + UInt space = getBindingSpace(chain, kind); + + switch(kind) { case LayoutResourceKind::Uniform: { - size_t offset = info.index; + UInt offset = index; // The HLSL `c` register space is logically grouped in 16-byte registers, // while we try to traffic in byte offsets. That means we need to pick @@ -3513,7 +3571,7 @@ struct EmitVisitor default: { Emit(": register("); - switch( info.kind ) + switch( kind ) { case LayoutResourceKind::ConstantBuffer: Emit("b"); @@ -3531,7 +3589,7 @@ struct EmitVisitor SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled HLSL register type"); break; } - Emit(info.index); + Emit(index); if(space) { Emit(", space"); @@ -3544,10 +3602,12 @@ struct EmitVisitor // Emit all the `register` semantics that are appropriate for a particular variable layout void emitHLSLRegisterSemantics( - RefPtr<VarLayout> layout, + EmitVarChain* chain, char const* uniformSemanticSpelling = "register") { - if (!layout) return; + if (!chain) return; + + auto layout = chain->varLayout; switch( context->shared->target ) { @@ -3560,10 +3620,21 @@ struct EmitVisitor for( auto rr : layout->resourceInfos ) { - emitHLSLRegisterSemantic(rr, getSpaceOffset(layout), uniformSemanticSpelling); + emitHLSLRegisterSemantic(rr.kind, chain, uniformSemanticSpelling); } } + void emitHLSLRegisterSemantics( + VarLayout* varLayout, + char const* uniformSemanticSpelling = "register") + { + if(!varLayout) + return; + + EmitVarChain chain(varLayout); + emitHLSLRegisterSemantics(&chain, uniformSemanticSpelling); + } + static RefPtr<VarLayout> maybeFetchLayout( RefPtr<Decl> decl, RefPtr<VarLayout> layout) @@ -3584,63 +3655,55 @@ struct EmitVisitor } void emitHLSLParameterGroupFieldLayoutSemantics( - RefPtr<VarLayout> layout, - RefPtr<VarLayout> fieldLayout) + EmitVarChain* chain) { - for( auto rr : fieldLayout->resourceInfos ) - { - auto kind = rr.kind; - - auto offsetResource = rr; + if(!chain) + return; - UInt spaceOffset = 0; - if(layout - && kind != LayoutResourceKind::Uniform) - { - // Add the base index from the cbuffer into the index of the field - // - // TODO(tfoley): consider maybe not doing this, since it actually - // complicates logic around constant buffers... - - // If the member of the cbuffer uses a resource, we would typically - // expect to see that the `cbuffer` itself shows up as using that - // resource too. - auto cbufferResource = layout->FindResourceInfo(kind); - if(cbufferResource) - { - offsetResource.index += cbufferResource->index; - offsetResource.space += cbufferResource->space; - } + auto layout = chain->varLayout; + for( auto rr : layout->resourceInfos ) + { + emitHLSLRegisterSemantic(rr.kind, chain, "packoffset"); + } + } - spaceOffset = getSpaceOffset(layout); - } - emitHLSLRegisterSemantic(offsetResource, spaceOffset, "packoffset"); - } + void emitHLSLParameterGroupFieldLayoutSemantics( + RefPtr<VarLayout> fieldLayout, + EmitVarChain* inChain) + { + EmitVarChain chain(fieldLayout, inChain); + emitHLSLParameterGroupFieldLayoutSemantics(&chain); } void emitHLSLParameterBlockDecl( RefPtr<VarDeclBase> varDecl, RefPtr<ParameterBlockType> parameterBlockType, - RefPtr<VarLayout> layout) + RefPtr<VarLayout> varLayout) { + EmitVarChain blockChain(varLayout); + Emit("cbuffer "); emitName(varDecl); // We expect to always have layout information - layout = maybeFetchLayout(varDecl, layout); - SLANG_RELEASE_ASSERT(layout); + varLayout = maybeFetchLayout(varDecl, varLayout); + SLANG_RELEASE_ASSERT(varLayout); // We expect the layout to be for a parameter group type... - RefPtr<ParameterGroupTypeLayout> bufferLayout = layout->typeLayout.As<ParameterGroupTypeLayout>(); + RefPtr<ParameterGroupTypeLayout> bufferLayout = varLayout->typeLayout.As<ParameterGroupTypeLayout>(); SLANG_RELEASE_ASSERT(bufferLayout); + RefPtr<VarLayout> containerVarLayout = bufferLayout->containerVarLayout; + EmitVarChain containerChain(containerVarLayout, &blockChain); + + RefPtr<VarLayout> elementVarLayout = bufferLayout->elementVarLayout; + EmitVarChain elementChain(elementVarLayout, &blockChain); + EmitSemantics(varDecl, kESemanticMask_None); - auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer); - SLANG_RELEASE_ASSERT(info); - emitHLSLRegisterSemantic(*info, getSpaceOffset(layout)); + emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain); Emit("\n{\n"); @@ -3654,13 +3717,12 @@ struct EmitVisitor // RefPtr<Type> elementType = parameterBlockType->elementType; - RefPtr<TypeLayout> elementTypeLayout = bufferLayout->offsetElementTypeLayout; EmitType(elementType, varDecl->getName()); // The layout for the field ends up coming from the layout // for the parameter block as a whole. - emitHLSLParameterGroupFieldLayoutSemantics(nullptr, layout); + emitHLSLParameterGroupFieldLayoutSemantics(&elementChain); Emit(";\n"); Emit("}\n"); @@ -3669,11 +3731,11 @@ struct EmitVisitor void emitHLSLParameterGroupDecl( RefPtr<VarDeclBase> varDecl, RefPtr<ParameterGroupType> parameterGroupType, - RefPtr<VarLayout> layout) + RefPtr<VarLayout> varLayout) { if( auto parameterBlockType = parameterGroupType->As<ParameterBlockType>()) { - emitHLSLParameterBlockDecl(varDecl, parameterBlockType, layout); + emitHLSLParameterBlockDecl(varDecl, parameterBlockType, varLayout); return; } if( auto textureBufferType = parameterGroupType->As<TextureBufferType>() ) @@ -3685,18 +3747,26 @@ struct EmitVisitor Emit("cbuffer "); } + EmitVarChain blockChain(varLayout); + // The data type that describes where stuff in the constant buffer should go RefPtr<Type> dataType = parameterGroupType->elementType; // We expect to always have layout information - layout = maybeFetchLayout(varDecl, layout); - SLANG_RELEASE_ASSERT(layout); + varLayout = maybeFetchLayout(varDecl, varLayout); + SLANG_RELEASE_ASSERT(varLayout); // We expect the layout to be for a structured type... - RefPtr<ParameterGroupTypeLayout> bufferLayout = layout->typeLayout.As<ParameterGroupTypeLayout>(); + RefPtr<ParameterGroupTypeLayout> bufferLayout = varLayout->typeLayout.As<ParameterGroupTypeLayout>(); SLANG_RELEASE_ASSERT(bufferLayout); - RefPtr<StructTypeLayout> structTypeLayout = bufferLayout->offsetElementTypeLayout.As<StructTypeLayout>(); + auto containerVarLayout = bufferLayout->containerVarLayout; + EmitVarChain containerChain(containerVarLayout, &blockChain); + + auto elementVarLayout = bufferLayout->elementVarLayout; + EmitVarChain elementChain(elementVarLayout, &blockChain); + + RefPtr<StructTypeLayout> structTypeLayout = bufferLayout->elementVarLayout->typeLayout.As<StructTypeLayout>(); SLANG_RELEASE_ASSERT(structTypeLayout); @@ -3712,9 +3782,7 @@ struct EmitVisitor EmitSemantics(varDecl, kESemanticMask_None); - auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer); - SLANG_RELEASE_ASSERT(info); - emitHLSLRegisterSemantic(*info, getSpaceOffset(layout)); + emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain); Emit("\n{\n"); @@ -3743,7 +3811,7 @@ struct EmitVisitor SLANG_RELEASE_ASSERT(fieldLayout->varDecl.GetName() == field.GetName()); // Emit explicit layout annotations for every field - emitHLSLParameterGroupFieldLayoutSemantics(layout, fieldLayout); + emitHLSLParameterGroupFieldLayoutSemantics(fieldLayout, &elementChain); emitVarDeclInit(field); @@ -3763,11 +3831,17 @@ struct EmitVisitor } void emitGLSLLayoutQualifier( - VarLayout::ResourceInfo const& info, - UInt spaceOffset) + LayoutResourceKind kind, + EmitVarChain* chain) { - UInt space = info.space + spaceOffset; - switch(info.kind) + if(!chain) + return; + if(!chain->varLayout->FindResourceInfo(kind)) + return; + + UInt index = getBindingOffset(chain, kind); + UInt space = getBindingSpace(chain, kind); + switch(kind) { case LayoutResourceKind::Uniform: { @@ -3794,7 +3868,7 @@ struct EmitVisitor requireGLSLExtension("GL_ARB_enhanced_layouts"); Emit("layout(offset = "); - Emit(info.index); + Emit(index); Emit(")\n"); } } @@ -3803,13 +3877,13 @@ struct EmitVisitor case LayoutResourceKind::VertexInput: case LayoutResourceKind::FragmentOutput: Emit("layout(location = "); - Emit(info.index); + Emit(index); Emit(")\n"); break; case LayoutResourceKind::SpecializationConstant: Emit("layout(constant_id = "); - Emit(info.index); + Emit(index); Emit(")\n"); break; @@ -3819,7 +3893,7 @@ struct EmitVisitor case LayoutResourceKind::SamplerState: case LayoutResourceKind::DescriptorTableSlot: Emit("layout(binding = "); - Emit(info.index); + Emit(index); if(space) { Emit(", set = "); @@ -3835,15 +3909,9 @@ struct EmitVisitor } } - UInt getSpaceOffset(VarLayout* layout) - { - if (auto resInfo = layout->FindResourceInfo(LayoutResourceKind::RegisterSpace)) - return resInfo->index; - return 0; - } - void emitGLSLLayoutQualifiers( RefPtr<VarLayout> layout, + EmitVarChain* inChain, LayoutResourceKind filter = LayoutResourceKind::None) { if(!layout) return; @@ -3857,7 +3925,7 @@ struct EmitVisitor break; } - UInt spaceOffset = getSpaceOffset(layout); + EmitVarChain chain(layout, inChain); for( auto info : layout->resourceInfos ) { @@ -3868,28 +3936,36 @@ struct EmitVisitor continue; } - emitGLSLLayoutQualifier(info, spaceOffset); + emitGLSLLayoutQualifier(info.kind, &chain); } } void emitGLSLParameterBlockDecl( RefPtr<VarDeclBase> varDecl, RefPtr<ParameterBlockType> parameterBlockType, - RefPtr<VarLayout> layout) + RefPtr<VarLayout> varLayout) { + EmitVarChain blockChain(varLayout); + + RefPtr<ParameterGroupTypeLayout> bufferLayout = varLayout->typeLayout.As<ParameterGroupTypeLayout>(); + SLANG_RELEASE_ASSERT(bufferLayout); + + auto containerVarLayout = bufferLayout->containerVarLayout; + EmitVarChain containerChain(containerVarLayout, &blockChain); + + auto elementVarLayout = bufferLayout->elementVarLayout; + EmitVarChain elementChain(elementVarLayout, &blockChain); + EmitModifiers(varDecl); - emitGLSLLayoutQualifiers(layout); + emitGLSLLayoutQualifiers(containerVarLayout, &blockChain); Emit("uniform "); emitName(varDecl); Emit("\n{\n"); - RefPtr<ParameterGroupTypeLayout> bufferLayout = layout->typeLayout.As<ParameterGroupTypeLayout>(); - SLANG_RELEASE_ASSERT(bufferLayout); RefPtr<Type> elementType = parameterBlockType->elementType; - RefPtr<TypeLayout> elementTypeLayout = bufferLayout->offsetElementTypeLayout; EmitType(elementType, varDecl->getName()); Emit(";\n"); @@ -3900,11 +3976,11 @@ struct EmitVisitor void emitGLSLParameterGroupDecl( RefPtr<VarDeclBase> varDecl, RefPtr<ParameterGroupType> parameterGroupType, - RefPtr<VarLayout> layout) + RefPtr<VarLayout> varLayout) { if( auto parameterBlockType = parameterGroupType->As<ParameterBlockType>()) { - emitGLSLParameterBlockDecl(varDecl, parameterBlockType, layout); + emitGLSLParameterBlockDecl(varDecl, parameterBlockType, varLayout); return; } @@ -3913,19 +3989,28 @@ struct EmitVisitor // We expect the layout, if present, to be for a structured type... RefPtr<StructTypeLayout> structTypeLayout; - if (layout) + + EmitVarChain blockChain; + if (varLayout) { + blockChain = EmitVarChain(varLayout); - auto typeLayout = layout->typeLayout; + auto typeLayout = varLayout->typeLayout; if (auto bufferLayout = typeLayout.As<ParameterGroupTypeLayout>()) { - typeLayout = bufferLayout->offsetElementTypeLayout; + typeLayout = bufferLayout->elementVarLayout->getTypeLayout(); + + emitGLSLLayoutQualifiers(bufferLayout->containerVarLayout, &blockChain); + } + else + { + // Fallback: we somehow have a messed up layout + emitGLSLLayoutQualifiers(varLayout, nullptr); } + // We expect the element type to be structured. structTypeLayout = typeLayout.As<StructTypeLayout>(); SLANG_RELEASE_ASSERT(structTypeLayout); - - emitGLSLLayoutQualifiers(layout); } @@ -4084,15 +4169,15 @@ struct EmitVisitor { if (decl->HasModifier<InModifier>()) { - emitGLSLLayoutQualifiers(layout, LayoutResourceKind::VertexInput); + emitGLSLLayoutQualifiers(layout, nullptr, LayoutResourceKind::VertexInput); } else if (decl->HasModifier<OutModifier>()) { - emitGLSLLayoutQualifiers(layout, LayoutResourceKind::FragmentOutput); + emitGLSLLayoutQualifiers(layout, nullptr, LayoutResourceKind::FragmentOutput); } else { - emitGLSLLayoutQualifiers(layout); + emitGLSLLayoutQualifiers(layout, nullptr); } // If we have a uniform that wasn't tagged `uniform` in GLSL, then fix that here @@ -6395,7 +6480,7 @@ emitDeclImpl(decl, nullptr); { // Layout-related modifiers need to come before the declaration, // so deal with them here. - emitGLSLLayoutQualifiers(layout); + emitGLSLLayoutQualifiers(layout, nullptr); // try to emit an appropriate leading qualifier for (auto rr : layout->resourceInfos) @@ -6436,26 +6521,33 @@ emitDeclImpl(decl, nullptr); emit("_S"); Emit(ctx->shared->uniqueIDCounter++); - auto layout = getVarLayout(ctx, varDecl); - assert(layout); - - auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer); - SLANG_RELEASE_ASSERT(info); - emitHLSLRegisterSemantic(*info, getSpaceOffset(layout)); + auto varLayout = getVarLayout(ctx, varDecl); + assert(varLayout); - emit("\n{\n"); + EmitVarChain blockChain(varLayout); - auto elementType = type->getElementType(); + EmitVarChain containerChain = blockChain; + EmitVarChain elementChain = blockChain; - auto typeLayout = layout->typeLayout; + auto typeLayout = varLayout->typeLayout; if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() ) { - typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout; + containerChain = EmitVarChain(parameterGroupTypeLayout->containerVarLayout, &blockChain); + elementChain = EmitVarChain(parameterGroupTypeLayout->elementVarLayout, &blockChain); + + typeLayout = parameterGroupTypeLayout->elementVarLayout->getTypeLayout(); } + emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain); + + emit("\n{\n"); + + auto elementType = type->getElementType(); + + emitIRType(ctx, elementType, getIRName(varDecl)); - emitHLSLParameterGroupFieldLayoutSemantics(nullptr, layout); + emitHLSLParameterGroupFieldLayoutSemantics(&elementChain); emit(";\n"); emit("}\n"); @@ -6475,23 +6567,30 @@ emitDeclImpl(decl, nullptr); emit("cbuffer "); emit(getIRName(varDecl)); - auto layout = getVarLayout(ctx, varDecl); - assert(layout); - - auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer); - SLANG_RELEASE_ASSERT(info); - emitHLSLRegisterSemantic(*info, getSpaceOffset(layout)); + auto varLayout = getVarLayout(ctx, varDecl); + assert(varLayout); - emit("\n{\n"); + EmitVarChain blockChain(varLayout); - auto elementType = type->getElementType(); + EmitVarChain containerChain = blockChain; + EmitVarChain elementChain = blockChain; - auto typeLayout = layout->typeLayout; + auto typeLayout = varLayout->typeLayout; if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() ) { - typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout; + containerChain = EmitVarChain(parameterGroupTypeLayout->containerVarLayout, &blockChain); + elementChain = EmitVarChain(parameterGroupTypeLayout->elementVarLayout, &blockChain); + + typeLayout = parameterGroupTypeLayout->elementVarLayout->typeLayout; } + emitHLSLRegisterSemantic(LayoutResourceKind::ConstantBuffer, &containerChain); + + emit("\n{\n"); + + auto elementType = type->getElementType(); + + if(auto declRefType = elementType->As<DeclRefType>()) { if(auto structDeclRef = declRefType->declRef.As<StructDecl>()) @@ -6522,7 +6621,7 @@ emitDeclImpl(decl, nullptr); emitIRType(ctx, fieldType, getIRName(ff)); - emitHLSLParameterGroupFieldLayoutSemantics(layout, fieldLayout); + emitHLSLParameterGroupFieldLayoutSemantics(fieldLayout, &elementChain); emit(";\n"); } @@ -6541,15 +6640,25 @@ emitDeclImpl(decl, nullptr); IRGlobalVar* varDecl, UniformParameterGroupType* type) { - auto layout = getVarLayout(ctx, varDecl); - assert(layout); + auto varLayout = getVarLayout(ctx, varDecl); + assert(varLayout); - auto info = layout->FindResourceInfo(LayoutResourceKind::DescriptorTableSlot); - if (info) + EmitVarChain blockChain(varLayout); + + EmitVarChain containerChain = blockChain; + EmitVarChain elementChain = blockChain; + + auto typeLayout = varLayout->typeLayout; + if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() ) { - emitGLSLLayoutQualifier(*info, getSpaceOffset(layout)); + containerChain = EmitVarChain(parameterGroupTypeLayout->containerVarLayout, &blockChain); + elementChain = EmitVarChain(parameterGroupTypeLayout->elementVarLayout, &blockChain); + + typeLayout = parameterGroupTypeLayout->elementVarLayout->typeLayout; } + emitGLSLLayoutQualifier(LayoutResourceKind::DescriptorTableSlot, &containerChain); + if(type->As<GLSLShaderStorageBufferType>()) { emit("layout(std430) buffer "); @@ -6566,12 +6675,6 @@ emitDeclImpl(decl, nullptr); auto elementType = type->getElementType(); - auto typeLayout = layout->typeLayout; - if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() ) - { - typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout; - } - if(auto declRefType = elementType->As<DeclRefType>()) { if(auto structDeclRef = declRefType->declRef.As<StructDecl>()) diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index 7068ecea4..cc2c6b289 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -581,7 +581,7 @@ SLANG_API SlangParameterCategory spReflectionTypeLayout_GetParameterCategory(Sla if (auto parameterGroupTypeLayout = dynamic_cast<ParameterGroupTypeLayout*>(typeLayout)) { - typeLayout = parameterGroupTypeLayout->containerTypeLayout; + typeLayout = parameterGroupTypeLayout->containerVarLayout->typeLayout; } return getParameterCategory(typeLayout); @@ -594,7 +594,7 @@ SLANG_API unsigned spReflectionTypeLayout_GetCategoryCount(SlangReflectionTypeLa if (auto parameterGroupTypeLayout = dynamic_cast<ParameterGroupTypeLayout*>(typeLayout)) { - typeLayout = parameterGroupTypeLayout->containerTypeLayout; + typeLayout = parameterGroupTypeLayout->containerVarLayout->typeLayout; } return (unsigned) typeLayout->resourceInfos.Count(); @@ -607,7 +607,7 @@ SLANG_API SlangParameterCategory spReflectionTypeLayout_GetCategoryByIndex(Slang if (auto parameterGroupTypeLayout = dynamic_cast<ParameterGroupTypeLayout*>(typeLayout)) { - typeLayout = parameterGroupTypeLayout->containerTypeLayout; + typeLayout = parameterGroupTypeLayout->containerVarLayout->typeLayout; } return typeLayout->resourceInfos[index].kind; diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp index da1337778..9689fde0c 100644 --- a/source/slang/type-layout.cpp +++ b/source/slang/type-layout.cpp @@ -1065,22 +1065,29 @@ createParameterGroupTypeLayout( // Note: at the moment, constant buffers apply their own offsetting // logic elsewhere, so we need to only do this logic for parameter blocks RefPtr<TypeLayout> offsetTypeLayout = applyOffsetToTypeLayout(rawElementTypeLayout, containerTypeLayout); - - typeLayout->containerTypeLayout = containerTypeLayout; typeLayout->offsetElementTypeLayout = offsetTypeLayout; + + RefPtr<VarLayout> containerVarLayout = new VarLayout(); + containerVarLayout->typeLayout = containerTypeLayout; + for( auto typeResInfo : containerTypeLayout->resourceInfos ) + { + containerVarLayout->findOrAddResourceInfo(typeResInfo.kind); + } + typeLayout->containerVarLayout = containerVarLayout; + // We will construct a dummy variable layout to represent the offsettting // that needs to be applied to the element type to put it after the // container. RefPtr<VarLayout> elementVarLayout = new VarLayout(); elementVarLayout->typeLayout = rawElementTypeLayout; - for (auto containerResourceInfo : containerTypeLayout->resourceInfos) + for( auto elementTypeResInfo : rawElementTypeLayout->resourceInfos ) { - auto kind = containerResourceInfo.kind; - if (auto elementResourceInfo = rawElementTypeLayout->FindResourceInfo(kind)) + auto kind = elementTypeResInfo.kind; + auto elementVarResInfo = elementVarLayout->findOrAddResourceInfo(kind); + if( auto containerTypeResInfo = containerTypeLayout->FindResourceInfo(kind) ) { - auto varResourceInfo = elementVarLayout->findOrAddResourceInfo(kind); - varResourceInfo->index += containerResourceInfo.count; + elementVarResInfo->index += containerTypeResInfo->count; } } typeLayout->elementVarLayout = elementVarLayout; diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index fc2007437..6874fc460 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -307,11 +307,13 @@ public: class ParameterGroupTypeLayout : public TypeLayout { public: - // The layout of the "container" type itself. + // 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. - RefPtr<TypeLayout> containerTypeLayout; + // 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 |
