summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2017-12-14 11:51:29 -0800
committerGitHub <noreply@github.com>2017-12-14 11:51:29 -0800
commit4137f9d4a58462ed94ed658ac0d722c830c3eb89 (patch)
tree74e89ad6deb13e23a4a2a72020e87219c9a1879e /source
parent6d6142122b15461d6c8cabdb31292b0de688ba35 (diff)
More fixups for Vulkan parameter block bindings (#309)
I'm adding a small cross-compilation test to try to make sure that we are testing the binding generation for GLSL output. We probably still need a more complex test that uses multiple blocks, plus variables not in a block. The big changes here are: - Change the `containerTypeLayout` field to a `containerVarLayout` in the `ParameterGroupTypeLayout`, so that we can store the base offsets for the fields in a uniform fashion (even though these will all be zero). - Switch the emit logic to carefully use either the container or element var layout depending on what they are emitting bindings for. This involved adding something akin to the "reflection path" notion that Falcor has to use, but only for the emit step.
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp353
-rw-r--r--source/slang/reflection.cpp6
-rw-r--r--source/slang/type-layout.cpp21
-rw-r--r--source/slang/type-layout.h8
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