summaryrefslogtreecommitdiffstats
path: root/source/slang/emit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/emit.cpp')
-rw-r--r--source/slang/emit.cpp100
1 files changed, 75 insertions, 25 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 09d209f6e..33fd46bdb 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -3454,10 +3454,13 @@ struct EmitVisitor
// Emit a single `regsiter` semantic, as appropriate for a given resource-type-specific layout info
void emitHLSLRegisterSemantic(
VarLayout::ResourceInfo const& info,
+ UInt spaceOffset,
// Keyword to use in the uniform case (`register` for globals, `packoffset` inside a `cbuffer`)
char const* uniformSemanticSpelling = "register")
{
+ UInt space = info.space + spaceOffset;
+
switch(info.kind)
{
case LayoutResourceKind::Uniform:
@@ -3529,10 +3532,10 @@ struct EmitVisitor
break;
}
Emit(info.index);
- if(info.space)
+ if(space)
{
Emit(", space");
- Emit(info.space);
+ Emit(space);
}
Emit(")");
}
@@ -3557,7 +3560,7 @@ struct EmitVisitor
for( auto rr : layout->resourceInfos )
{
- emitHLSLRegisterSemantic(rr, uniformSemanticSpelling);
+ emitHLSLRegisterSemantic(rr, getSpaceOffset(layout), uniformSemanticSpelling);
}
}
@@ -3590,6 +3593,7 @@ struct EmitVisitor
auto offsetResource = rr;
+ UInt spaceOffset = 0;
if(layout
&& kind != LayoutResourceKind::Uniform)
{
@@ -3607,9 +3611,11 @@ struct EmitVisitor
offsetResource.index += cbufferResource->index;
offsetResource.space += cbufferResource->space;
}
+
+ spaceOffset = getSpaceOffset(layout);
}
- emitHLSLRegisterSemantic(offsetResource, "packoffset");
+ emitHLSLRegisterSemantic(offsetResource, spaceOffset, "packoffset");
}
}
@@ -3634,7 +3640,7 @@ struct EmitVisitor
auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer);
SLANG_RELEASE_ASSERT(info);
- emitHLSLRegisterSemantic(*info);
+ emitHLSLRegisterSemantic(*info, getSpaceOffset(layout));
Emit("\n{\n");
@@ -3648,7 +3654,7 @@ struct EmitVisitor
//
RefPtr<Type> elementType = parameterBlockType->elementType;
- RefPtr<TypeLayout> elementTypeLayout = bufferLayout->elementTypeLayout;
+ RefPtr<TypeLayout> elementTypeLayout = bufferLayout->offsetElementTypeLayout;
EmitType(elementType, varDecl->getName());
@@ -3690,7 +3696,7 @@ struct EmitVisitor
RefPtr<ParameterGroupTypeLayout> bufferLayout = layout->typeLayout.As<ParameterGroupTypeLayout>();
SLANG_RELEASE_ASSERT(bufferLayout);
- RefPtr<StructTypeLayout> structTypeLayout = bufferLayout->elementTypeLayout.As<StructTypeLayout>();
+ RefPtr<StructTypeLayout> structTypeLayout = bufferLayout->offsetElementTypeLayout.As<StructTypeLayout>();
SLANG_RELEASE_ASSERT(structTypeLayout);
@@ -3708,7 +3714,7 @@ struct EmitVisitor
auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer);
SLANG_RELEASE_ASSERT(info);
- emitHLSLRegisterSemantic(*info);
+ emitHLSLRegisterSemantic(*info, getSpaceOffset(layout));
Emit("\n{\n");
@@ -3757,8 +3763,10 @@ struct EmitVisitor
}
void emitGLSLLayoutQualifier(
- VarLayout::ResourceInfo const& info)
+ VarLayout::ResourceInfo const& info,
+ UInt spaceOffset)
{
+ UInt space = info.space + spaceOffset;
switch(info.kind)
{
case LayoutResourceKind::Uniform:
@@ -3812,10 +3820,10 @@ struct EmitVisitor
case LayoutResourceKind::DescriptorTableSlot:
Emit("layout(binding = ");
Emit(info.index);
- if(info.space)
+ if(space)
{
Emit(", set = ");
- Emit(info.space);
+ Emit(space);
}
Emit(")\n");
break;
@@ -3827,6 +3835,13 @@ struct EmitVisitor
}
}
+ UInt getSpaceOffset(VarLayout* layout)
+ {
+ if (auto resInfo = layout->FindResourceInfo(LayoutResourceKind::RegisterSpace))
+ return resInfo->index;
+ return 0;
+ }
+
void emitGLSLLayoutQualifiers(
RefPtr<VarLayout> layout,
LayoutResourceKind filter = LayoutResourceKind::None)
@@ -3842,6 +3857,8 @@ struct EmitVisitor
break;
}
+ UInt spaceOffset = getSpaceOffset(layout);
+
for( auto info : layout->resourceInfos )
{
// Skip info that doesn't match our filter
@@ -3851,15 +3868,46 @@ struct EmitVisitor
continue;
}
- emitGLSLLayoutQualifier(info);
+ emitGLSLLayoutQualifier(info, spaceOffset);
}
}
+ void emitGLSLParameterBlockDecl(
+ RefPtr<VarDeclBase> varDecl,
+ RefPtr<ParameterBlockType> parameterBlockType,
+ RefPtr<VarLayout> layout)
+ {
+ EmitModifiers(varDecl);
+ emitGLSLLayoutQualifiers(layout);
+ 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");
+
+ Emit("};\n");
+ }
+
void emitGLSLParameterGroupDecl(
RefPtr<VarDeclBase> varDecl,
RefPtr<ParameterGroupType> parameterGroupType,
RefPtr<VarLayout> layout)
{
+ if( auto parameterBlockType = parameterGroupType->As<ParameterBlockType>())
+ {
+ emitGLSLParameterBlockDecl(varDecl, parameterBlockType, layout);
+ return;
+ }
+
// The data type that describes where stuff in the constant buffer should go
RefPtr<Type> dataType = parameterGroupType->elementType;
@@ -3871,7 +3919,7 @@ struct EmitVisitor
auto typeLayout = layout->typeLayout;
if (auto bufferLayout = typeLayout.As<ParameterGroupTypeLayout>())
{
- typeLayout = bufferLayout->elementTypeLayout;
+ typeLayout = bufferLayout->offsetElementTypeLayout;
}
structTypeLayout = typeLayout.As<StructTypeLayout>();
@@ -3884,7 +3932,13 @@ struct EmitVisitor
EmitModifiers(varDecl);
// Emit an apprpriate declaration keyword based on the kind of block
- if (parameterGroupType->As<ConstantBufferType>())
+ if (parameterGroupType->As<GLSLShaderStorageBufferType>())
+ {
+ Emit("buffer");
+ }
+ // Note: tested `buffer` case before `uniform`, since `GLSLShaderStorageBufferType`
+ // is also a subclass of `UniformParameterGroupType`.
+ else if (parameterGroupType->As<UniformParameterGroupType>())
{
Emit("uniform");
}
@@ -3896,10 +3950,6 @@ struct EmitVisitor
{
Emit("out");
}
- else if (parameterGroupType->As<GLSLShaderStorageBufferType>())
- {
- Emit("buffer");
- }
else
{
SLANG_DIAGNOSE_UNEXPECTED(getSink(), varDecl, "unhandled GLSL shader parameter kind");
@@ -6391,7 +6441,7 @@ emitDeclImpl(decl, nullptr);
auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer);
SLANG_RELEASE_ASSERT(info);
- emitHLSLRegisterSemantic(*info);
+ emitHLSLRegisterSemantic(*info, getSpaceOffset(layout));
emit("\n{\n");
@@ -6400,7 +6450,7 @@ emitDeclImpl(decl, nullptr);
auto typeLayout = layout->typeLayout;
if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() )
{
- typeLayout = parameterGroupTypeLayout->elementTypeLayout;
+ typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout;
}
emitIRType(ctx, elementType, getIRName(varDecl));
@@ -6430,7 +6480,7 @@ emitDeclImpl(decl, nullptr);
auto info = layout->FindResourceInfo(LayoutResourceKind::ConstantBuffer);
SLANG_RELEASE_ASSERT(info);
- emitHLSLRegisterSemantic(*info);
+ emitHLSLRegisterSemantic(*info, getSpaceOffset(layout));
emit("\n{\n");
@@ -6439,7 +6489,7 @@ emitDeclImpl(decl, nullptr);
auto typeLayout = layout->typeLayout;
if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() )
{
- typeLayout = parameterGroupTypeLayout->elementTypeLayout;
+ typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout;
}
if(auto declRefType = elementType->As<DeclRefType>())
@@ -6497,7 +6547,7 @@ emitDeclImpl(decl, nullptr);
auto info = layout->FindResourceInfo(LayoutResourceKind::DescriptorTableSlot);
if (info)
{
- emitGLSLLayoutQualifier(*info);
+ emitGLSLLayoutQualifier(*info, getSpaceOffset(layout));
}
if(type->As<GLSLShaderStorageBufferType>())
@@ -6519,7 +6569,7 @@ emitDeclImpl(decl, nullptr);
auto typeLayout = layout->typeLayout;
if( auto parameterGroupTypeLayout = typeLayout.As<ParameterGroupTypeLayout>() )
{
- typeLayout = parameterGroupTypeLayout->elementTypeLayout;
+ typeLayout = parameterGroupTypeLayout->offsetElementTypeLayout;
}
if(auto declRefType = elementType->As<DeclRefType>())
@@ -6969,7 +7019,7 @@ StructTypeLayout* getGlobalStructLayout(
// and hope that the global-scope block (`$Globals`) gets auto-assigned
// the same location that we manually asigned it.
- auto elementTypeLayout = globalConstantBufferLayout->elementTypeLayout;
+ auto elementTypeLayout = globalConstantBufferLayout->offsetElementTypeLayout;
auto elementTypeStructLayout = elementTypeLayout.As<StructTypeLayout>();
// We expect all constant buffers to contain `struct` types for now