summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang2
-rw-r--r--source/slang/hlsl.meta.slang9
-rw-r--r--source/slang/slang-ast-builder.cpp37
-rw-r--r--source/slang/slang-ast-builder.h13
-rw-r--r--source/slang/slang-ast-type.h31
-rw-r--r--source/slang/slang-check-decl.cpp43
-rw-r--r--source/slang/slang-check-impl.h2
-rw-r--r--source/slang/slang-check-shader.cpp2
-rw-r--r--source/slang/slang-check-type.cpp7
-rw-r--r--source/slang/slang-emit-glsl.cpp27
-rw-r--r--source/slang/slang-emit-hlsl.cpp7
-rw-r--r--source/slang/slang-emit.cpp1
-rw-r--r--source/slang/slang-ir-collect-global-uniforms.cpp4
-rw-r--r--source/slang/slang-ir-entry-point-uniforms.cpp11
-rw-r--r--source/slang/slang-ir-entry-point-uniforms.h1
-rw-r--r--source/slang/slang-ir-insts.h2
-rw-r--r--source/slang/slang-ir-legalize-types.cpp23
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp20
-rw-r--r--source/slang/slang-ir-optix-entry-point-uniforms.cpp4
-rw-r--r--source/slang/slang-ir.cpp6
-rw-r--r--source/slang/slang-ir.h9
-rw-r--r--source/slang/slang-legalize-types.cpp42
-rw-r--r--source/slang/slang-legalize-types.h11
-rw-r--r--source/slang/slang-parameter-binding.cpp42
-rw-r--r--source/slang/slang-syntax.cpp5
-rw-r--r--source/slang/slang-type-layout.cpp59
-rw-r--r--source/slang/slang-type-layout.h4
-rw-r--r--source/slang/slang.cpp4
28 files changed, 351 insertions, 77 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 249a084b1..817e3c39d 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1871,7 +1871,7 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt)
//@ public:
-__generic<T>
+__generic<T, L:IBufferDataLayout = DefaultDataLayout>
__intrinsic_type($(kIROp_ConstantBufferType))
__magic_type(ConstantBufferType)
struct ConstantBuffer {}
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 7eb4af135..84beb3b4b 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -10,12 +10,14 @@ void __requireGLSLExtension(String extensionName);
/// Represents an interface for buffer data layout.
/// This interface is used as a base for defining specific data layouts for buffers.
[sealed]
+__magic_type(IBufferDataLayoutType)
interface IBufferDataLayout
{
}
/// @category misc_types
__intrinsic_type($(kIROp_DefaultBufferLayoutType))
+__magic_type(DefaultDataLayoutType)
struct DefaultDataLayout : IBufferDataLayout
{};
@@ -23,6 +25,7 @@ struct DefaultDataLayout : IBufferDataLayout
__intrinsic_type($(kIROp_Std140BufferLayoutType))
[require(spirv)]
[require(glsl)]
+__magic_type(Std140DataLayoutType)
struct Std140DataLayout : IBufferDataLayout
{};
@@ -30,11 +33,13 @@ struct Std140DataLayout : IBufferDataLayout
__intrinsic_type($(kIROp_Std430BufferLayoutType))
[require(spirv)]
[require(glsl)]
+__magic_type(Std430DataLayoutType)
struct Std430DataLayout : IBufferDataLayout
{};
/// @category misc_types
__intrinsic_type($(kIROp_ScalarBufferLayoutType))
+__magic_type(ScalarDataLayoutType)
struct ScalarDataLayout : IBufferDataLayout
{};
@@ -20588,7 +20593,7 @@ const char* kDynamicResourceCastableTypes[] = {
"SamplerState", "SamplerComparisonState",
- "ConstantBuffer<T>", "TextureBuffer<T>",
+ "ConstantBuffer<T, L>", "TextureBuffer<T>",
};
for (auto typeName : kDynamicResourceCastableTypes) {
@@ -20596,6 +20601,8 @@ for (auto typeName : kDynamicResourceCastableTypes) {
if (strstr(typeName, "StructuredBuffer<T, L>"))
sb << "__generic<T, L : IBufferDataLayout = DefaultDataLayout>\n";
+ else if (strstr(typeName, "ConstantBuffer<T, L>"))
+ sb << "__generic<T, L : IBufferDataLayout = DefaultDataLayout>\n";
else if (strstr(typeName, "Buffer<T>"))
sb << "__generic<T>\n";
}}}}
diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp
index 575c7268b..6ffaee7db 100644
--- a/source/slang/slang-ast-builder.cpp
+++ b/source/slang/slang-ast-builder.cpp
@@ -146,6 +146,16 @@ Type* SharedASTBuilder::getDiffInterfaceType()
return m_diffInterfaceType;
}
+Type* SharedASTBuilder::getIBufferDataLayoutType()
+{
+ if (!m_IBufferDataLayoutType)
+ {
+ auto decl = findMagicDecl("IBufferDataLayoutType");
+ m_IBufferDataLayoutType = DeclRefType::create(m_astBuilder, makeDeclRef<Decl>(decl));
+ }
+ return m_IBufferDataLayoutType;
+}
+
Type* SharedASTBuilder::getErrorType()
{
if (!m_errorType)
@@ -296,6 +306,23 @@ PtrType* ASTBuilder::getPtrType(Type* valueType, AddressSpace addrSpace)
return dynamicCast<PtrType>(getPtrType(valueType, addrSpace, "PtrType"));
}
+Type* ASTBuilder::getDefaultLayoutType()
+{
+ return getSpecializedBuiltinType({}, "DefaultDataLayoutType");
+}
+Type* ASTBuilder::getStd140LayoutType()
+{
+ return getSpecializedBuiltinType({}, "Std140DataLayoutType");
+}
+Type* ASTBuilder::getStd430LayoutType()
+{
+ return getSpecializedBuiltinType({}, "Std430DataLayoutType");
+}
+Type* ASTBuilder::getScalarLayoutType()
+{
+ return getSpecializedBuiltinType({}, "ScalarDataLayoutType");
+}
+
// Construct the type `Out<valueType>`
OutType* ASTBuilder::getOutType(Type* valueType)
{
@@ -358,9 +385,15 @@ ArrayExpressionType* ASTBuilder::getArrayType(Type* elementType, IntVal* element
getSpecializedBuiltinType(makeArrayView(args), "ArrayExpressionType"));
}
-ConstantBufferType* ASTBuilder::getConstantBufferType(Type* elementType)
+ConstantBufferType* ASTBuilder::getConstantBufferType(
+ Type* elementType,
+ Type* layoutType,
+ Val* layoutWitness)
{
- return as<ConstantBufferType>(getSpecializedBuiltinType(elementType, "ConstantBufferType"));
+ Val* args[] = {elementType, layoutType, layoutWitness};
+
+ return as<ConstantBufferType>(
+ getSpecializedBuiltinType(makeArrayView(args), "ConstantBufferType"));
}
ParameterBlockType* ASTBuilder::getParameterBlockType(Type* elementType)
diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h
index 22f6bb91e..bd5c9b4e3 100644
--- a/source/slang/slang-ast-builder.h
+++ b/source/slang/slang-ast-builder.h
@@ -39,6 +39,8 @@ public:
/// Get the `IDifferentiable` type
Type* getDiffInterfaceType();
+ Type* getIBufferDataLayoutType();
+
Type* getErrorType();
Type* getBottomType();
Type* getInitializerListType();
@@ -89,6 +91,7 @@ protected:
Type* m_bottomType = nullptr;
Type* m_initializerListType = nullptr;
Type* m_overloadedType = nullptr;
+ Type* m_IBufferDataLayoutType = nullptr;
// The following types are created lazily, such that part of their definition
// can be in the core module.
@@ -482,6 +485,11 @@ public:
Type* getSpecializedBuiltinType(Type* typeParam, const char* magicTypeName);
Type* getSpecializedBuiltinType(ArrayView<Val*> genericArgs, const char* magicTypeName);
+ Type* getDefaultLayoutType();
+ Type* getStd140LayoutType();
+ Type* getStd430LayoutType();
+ Type* getScalarLayoutType();
+
Type* getInitializerListType() { return m_sharedASTBuilder->getInitializerListType(); }
Type* getOverloadedType() { return m_sharedASTBuilder->getOverloadedType(); }
Type* getErrorType() { return m_sharedASTBuilder->getErrorType(); }
@@ -525,7 +533,10 @@ public:
IntVal* colCount,
IntVal* layout);
- ConstantBufferType* getConstantBufferType(Type* elementType);
+ ConstantBufferType* getConstantBufferType(
+ Type* elementType,
+ Type* layoutType,
+ Val* layoutIsILayout);
ParameterBlockType* getParameterBlockType(Type* elementType);
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index c55e0011f..c5c5de5d2 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -113,6 +113,36 @@ class BuiltinType : public DeclRefType
SLANG_ABSTRACT_AST_CLASS(BuiltinType)
};
+class DataLayoutType : public BuiltinType
+{
+ SLANG_ABSTRACT_AST_CLASS(DataLayoutType)
+};
+
+class IBufferDataLayoutType : public BuiltinType
+{
+ SLANG_AST_CLASS(IBufferDataLayoutType)
+};
+
+class DefaultDataLayoutType : public DataLayoutType
+{
+ SLANG_AST_CLASS(DefaultDataLayoutType)
+};
+
+class Std430DataLayoutType : public DataLayoutType
+{
+ SLANG_AST_CLASS(Std430DataLayoutType)
+};
+
+class Std140DataLayoutType : public DataLayoutType
+{
+ SLANG_AST_CLASS(Std140DataLayoutType)
+};
+
+class ScalarDataLayoutType : public DataLayoutType
+{
+ SLANG_AST_CLASS(ScalarDataLayoutType)
+};
+
class FeedbackType : public BuiltinType
{
SLANG_AST_CLASS(FeedbackType)
@@ -374,6 +404,7 @@ class ParameterGroupType : public PointerLikeType
class UniformParameterGroupType : public ParameterGroupType
{
SLANG_AST_CLASS(UniformParameterGroupType)
+ Type* getLayoutType();
};
class VaryingParameterGroupType : public ParameterGroupType
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 07d5dd1fa..251ce6a69 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -110,6 +110,7 @@ struct SemanticsDeclHeaderVisitor : public SemanticsDeclVisitorBase,
void checkMeshOutputDecl(VarDeclBase* varDecl);
void maybeApplyLayoutModifier(VarDeclBase* varDecl);
void checkVarDeclCommon(VarDeclBase* varDecl);
+ void checkPushConstantBufferType(VarDeclBase* varDecl);
void visitVarDecl(VarDecl* varDecl) { checkVarDeclCommon(varDecl); }
@@ -1707,6 +1708,10 @@ void SemanticsDeclHeaderVisitor::maybeApplyLayoutModifier(VarDeclBase* varDecl)
addModifier(varDecl, formatAttrib);
}
}
+ else
+ {
+ checkPushConstantBufferType(varDecl);
+ }
}
bool isSpecializationConstant(VarDeclBase* varDecl)
@@ -1721,6 +1726,32 @@ bool isSpecializationConstant(VarDeclBase* varDecl)
return false;
}
+void SemanticsDeclHeaderVisitor::checkPushConstantBufferType(VarDeclBase* varDecl)
+{
+ if (varDecl->findModifier<PushConstantAttribute>())
+ {
+ // If we see a ConstantBuffer<T, DefaultLayout> parameter marked as "push_constant", we need
+ // to set its type to ConstantBuffer<T, Std430>.
+ if (auto cbufferType = as<ConstantBufferType>(varDecl->type))
+ {
+ if (cbufferType->getLayoutType() == m_astBuilder->getDefaultLayoutType())
+ {
+ varDecl->type.type = getConstantBufferType(
+ cbufferType->getElementType(),
+ m_astBuilder->getStd430LayoutType());
+ }
+ }
+ else if (isGlobalShaderParameter(varDecl))
+ {
+ // If this is a global variable with [vk::push_constant] attribute,
+ // we need to make sure to wrap it in a `ConstantBuffer`.
+ //
+ varDecl->type.type =
+ getConstantBufferType(varDecl->type, m_astBuilder->getStd430LayoutType());
+ }
+ }
+}
+
void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
{
// A variable that didn't have an explicit type written must
@@ -1935,20 +1966,8 @@ void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
}
}
-
if (as<NamespaceDeclBase>(varDecl->parentDecl))
{
- // If this is a global variable with [vk::push_constant] attribute,
- // we need to make sure to wrap it in a `ConstantBuffer`.
-
- if (!as<ConstantBufferType>(varDecl->type))
- {
- if (varDecl->findModifier<PushConstantAttribute>())
- {
- varDecl->type.type = m_astBuilder->getConstantBufferType(varDecl->type);
- }
- }
-
if (getModuleDecl(varDecl)->hasModifier<GLSLModuleModifier>())
{
// If we are in GLSL compatiblity mode, we want to treat all global variables
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 95a6d00cc..95ec872a5 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -1149,6 +1149,8 @@ public:
TypeExp TranslateTypeNodeForced(TypeExp const& typeExp);
TypeExp TranslateTypeNode(TypeExp const& typeExp);
Type* getRemovedModifierType(ModifiedType* type, ModifierVal* modifier);
+ Type* getConstantBufferType(Type* elementType, Type* layoutType);
+
DeclRefType* getExprDeclRefType(Expr* expr);
/// Is `decl` usable as a static member?
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index 80c950c17..52a70034a 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -280,6 +280,8 @@ bool isUniformParameterType(Type* type)
return true;
if (as<SamplerStateType>(type))
return true;
+ if (as<PtrType>(type))
+ return true;
if (auto arrayType = as<ArrayExpressionType>(type))
return isUniformParameterType(arrayType->getElementType());
if (auto modType = as<ModifiedType>(type))
diff --git a/source/slang/slang-check-type.cpp b/source/slang/slang-check-type.cpp
index 34f16751b..d9691a828 100644
--- a/source/slang/slang-check-type.cpp
+++ b/source/slang/slang-check-type.cpp
@@ -101,6 +101,13 @@ Type* SemanticsVisitor::getRemovedModifierType(ModifiedType* modifiedType, Modif
return m_astBuilder->getModifiedType(modifiedType->getBase(), newModifiers);
}
+Type* SemanticsVisitor::getConstantBufferType(Type* elementType, Type* layoutType)
+{
+ auto iBufferDataLayoutType = m_astBuilder->getSharedASTBuilder()->getIBufferDataLayoutType();
+ auto witness = isSubtype(layoutType, iBufferDataLayoutType, IsSubTypeOptions());
+ return m_astBuilder->getConstantBufferType(elementType, layoutType, witness);
+}
+
Expr* SemanticsVisitor::ExpectATypeRepr(Expr* expr)
{
if (auto overloadedExpr = as<OverloadedExpr>(expr))
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 43ab7b74e..6c525d064 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -478,8 +478,31 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(
{
// uniform is implicitly read only
m_writer->emit("layout(");
- m_writer->emit(
- getTargetProgram()->getOptionSet().shouldUseScalarLayout() ? "scalar" : "std140");
+ if (getTargetProgram()->getOptionSet().shouldUseScalarLayout())
+ m_writer->emit("scalar");
+ else if (auto cbufferType = as<IRConstantBufferType>(type))
+ {
+ switch (cbufferType->getDataLayout()->getOp())
+ {
+ case kIROp_Std140BufferLayoutType:
+ m_writer->emit("std140");
+ break;
+ case kIROp_Std430BufferLayoutType:
+ m_writer->emit("std430");
+ break;
+ case kIROp_ScalarBufferLayoutType:
+ _requireGLSLExtension(toSlice("GL_EXT_scalar_block_layout"));
+ m_writer->emit("scalar");
+ break;
+ default:
+ m_writer->emit("std140");
+ break;
+ }
+ }
+ else
+ {
+ m_writer->emit("std140");
+ }
m_writer->emit(") uniform ");
}
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 26d37d1f5..824680b72 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -1310,6 +1310,13 @@ void HLSLSourceEmitter::emitSimpleTypeImpl(IRType* type)
_emitHLSLSubpassInputType(subpassType);
return;
}
+ else if (auto cbufferType = as<IRConstantBufferType>(type))
+ {
+ m_writer->emit("ConstantBuffer<");
+ emitType(cbufferType->getElementType());
+ m_writer->emit(" >");
+ return;
+ }
else if (auto structuredBufferType = as<IRHLSLStructuredBufferTypeBase>(type))
{
switch (structuredBufferType->getOp())
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 010b4bc92..326fc702d 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -642,6 +642,7 @@ Result linkAndOptimizeIR(
//
{
CollectEntryPointUniformParamsOptions passOptions;
+ passOptions.targetReq = targetRequest;
switch (target)
{
case CodeGenTarget::HostCPPSource:
diff --git a/source/slang/slang-ir-collect-global-uniforms.cpp b/source/slang/slang-ir-collect-global-uniforms.cpp
index cd03a61ef..1c833a294 100644
--- a/source/slang/slang-ir-collect-global-uniforms.cpp
+++ b/source/slang/slang-ir-collect-global-uniforms.cpp
@@ -155,7 +155,9 @@ struct CollectGlobalUniformParametersContext
IRType* wrapperParamType = wrapperStructType;
if (globalParameterGroupTypeLayout)
{
- auto wrapperParamGroupType = builder->getConstantBufferType(wrapperStructType);
+ auto wrapperParamGroupType = builder->getConstantBufferType(
+ wrapperStructType,
+ builder->getType(kIROp_DefaultBufferLayoutType));
wrapperParamType = wrapperParamGroupType;
}
diff --git a/source/slang/slang-ir-entry-point-uniforms.cpp b/source/slang/slang-ir-entry-point-uniforms.cpp
index 0dfdc2d8e..b3073a97d 100644
--- a/source/slang/slang-ir-entry-point-uniforms.cpp
+++ b/source/slang/slang-ir-entry-point-uniforms.cpp
@@ -403,7 +403,16 @@ struct CollectEntryPointUniformParams : PerEntryPointPass
// If we need a constant buffer, then the global
// shader parameter will be a `ConstantBuffer<paramStructType>`
//
- auto constantBufferType = builder.getConstantBufferType(paramStructType);
+ IRType* layoutType = nullptr;
+
+ if (m_options.targetReq->getOptionSet().getBoolOption(
+ CompilerOptionName::GLSLForceScalarLayout))
+ layoutType = builder.getType(kIROp_ScalarBufferLayoutType);
+ else if (isKhronosTarget(m_options.targetReq))
+ layoutType = builder.getType(kIROp_Std430BufferLayoutType);
+ else
+ layoutType = builder.getType(kIROp_DefaultBufferLayoutType);
+ auto constantBufferType = builder.getConstantBufferType(paramStructType, layoutType);
collectedParam = builder.createParam(constantBufferType);
}
else
diff --git a/source/slang/slang-ir-entry-point-uniforms.h b/source/slang/slang-ir-entry-point-uniforms.h
index 80bc0a781..21cee3c4e 100644
--- a/source/slang/slang-ir-entry-point-uniforms.h
+++ b/source/slang/slang-ir-entry-point-uniforms.h
@@ -12,6 +12,7 @@ struct CollectEntryPointUniformParamsOptions
// TODO(JS): Not sure if it makes sense to initialize to true or false. Go with false as
// seems to fit usage.
bool alwaysCreateCollectedParam = false;
+ TargetRequest* targetReq = nullptr;
};
/// Collect entry point uniform parameters into a wrapper `struct` and/or buffer
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 97989e9ce..fb06863d4 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -3719,7 +3719,7 @@ public:
return getFuncType(paramTypes.getCount(), paramTypes.getBuffer(), resultType);
}
- IRConstantBufferType* getConstantBufferType(IRType* elementType);
+ IRConstantBufferType* getConstantBufferType(IRType* elementType, IRType* layout);
IRGLSLOutputParameterGroupType* getGLSLOutputParameterGroupType(IRType* valueType);
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index 2af3c4c09..9154277f5 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -4016,12 +4016,15 @@ struct IRResourceTypeLegalizationContext : IRTypeLegalizationContext
bool isSimpleType(IRType*) override { return false; }
- LegalType createLegalUniformBufferType(IROp op, LegalType legalElementType) override
+ LegalType createLegalUniformBufferType(
+ IROp op,
+ LegalType legalElementType,
+ IRInst* layoutOperand) override
{
// The appropriate strategy for legalizing uniform buffers
// with resources inside already exists, so we can delegate to it.
//
- return createLegalUniformBufferTypeForResources(this, op, legalElementType);
+ return createLegalUniformBufferTypeForResources(this, op, legalElementType, layoutOperand);
}
};
@@ -4045,7 +4048,10 @@ struct IRExistentialTypeLegalizationContext : IRTypeLegalizationContext
bool isSimpleType(IRType*) override { return false; }
- LegalType createLegalUniformBufferType(IROp op, LegalType legalElementType) override
+ LegalType createLegalUniformBufferType(
+ IROp op,
+ LegalType legalElementType,
+ IRInst* layoutOperand) override
{
// We'll delegate the logic for creating uniform buffers
// over a mix of ordinary and existential-box types to
@@ -4054,7 +4060,11 @@ struct IRExistentialTypeLegalizationContext : IRTypeLegalizationContext
// TODO: We should eventually try to refactor this code
// so that related functionality is grouped together.
//
- return createLegalUniformBufferTypeForExistentials(this, op, legalElementType);
+ return createLegalUniformBufferTypeForExistentials(
+ this,
+ op,
+ legalElementType,
+ layoutOperand);
}
};
@@ -4090,7 +4100,10 @@ struct IREmptyTypeLegalizationContext : IRTypeLegalizationContext
return false;
}
- LegalType createLegalUniformBufferType(IROp, LegalType) override { return LegalType(); }
+ LegalType createLegalUniformBufferType(IROp, LegalType, IRInst*) override
+ {
+ return LegalType();
+ }
};
// The main entry points that are used when transforming IR code
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp
index 2f8631e18..bd3e350bc 100644
--- a/source/slang/slang-ir-lower-buffer-element-type.cpp
+++ b/source/slang/slang-ir-lower-buffer-element-type.cpp
@@ -1376,7 +1376,25 @@ IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetProgram* target, IRType* buf
}
case kIROp_ConstantBufferType:
case kIROp_ParameterBlockType:
- return IRTypeLayoutRules::getStd140();
+ {
+ auto parameterGroupType = as<IRUniformParameterGroupType>(bufferType);
+
+ auto layoutTypeOp = parameterGroupType->getDataLayout()
+ ? parameterGroupType->getDataLayout()->getOp()
+ : kIROp_DefaultBufferLayoutType;
+ switch (layoutTypeOp)
+ {
+ case kIROp_DefaultBufferLayoutType:
+ return IRTypeLayoutRules::getStd140();
+ case kIROp_Std140BufferLayoutType:
+ return IRTypeLayoutRules::getStd140();
+ case kIROp_Std430BufferLayoutType:
+ return IRTypeLayoutRules::getStd430();
+ case kIROp_ScalarBufferLayoutType:
+ return IRTypeLayoutRules::getNatural();
+ }
+ return IRTypeLayoutRules::getStd140();
+ }
case kIROp_PtrType:
return IRTypeLayoutRules::getNatural();
}
diff --git a/source/slang/slang-ir-optix-entry-point-uniforms.cpp b/source/slang/slang-ir-optix-entry-point-uniforms.cpp
index f29cbe222..dfa07ca67 100644
--- a/source/slang/slang-ir-optix-entry-point-uniforms.cpp
+++ b/source/slang/slang-ir-optix-entry-point-uniforms.cpp
@@ -253,7 +253,9 @@ struct CollectOptixEntryPointUniformParams : PerEntryPointPass
// TODO: reconcile this with OptiX, as the current logic works, but is still focused on
// VK/DXR..
//
- auto constantBufferType = builder.getConstantBufferType(paramStructType);
+ auto constantBufferType = builder.getConstantBufferType(
+ paramStructType,
+ builder.getType(kIROp_DefaultBufferLayoutType));
collectedParam = builder.createParam(constantBufferType);
// The global shader parameter should have the layout
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index e7f82f5ad..f6c662a98 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -3046,10 +3046,10 @@ IRWitnessTableIDType* IRBuilder::getWitnessTableIDType(IRType* baseType)
createIntrinsicInst(nullptr, kIROp_WitnessTableIDType, 1, (IRInst* const*)&baseType);
}
-IRConstantBufferType* IRBuilder::getConstantBufferType(IRType* elementType)
+IRConstantBufferType* IRBuilder::getConstantBufferType(IRType* elementType, IRType* layoutType)
{
- IRInst* operands[] = {elementType};
- return (IRConstantBufferType*)getType(kIROp_ConstantBufferType, 1, operands);
+ IRInst* operands[] = {elementType, layoutType};
+ return (IRConstantBufferType*)getType(kIROp_ConstantBufferType, 2, operands);
}
IRGLSLOutputParameterGroupType* IRBuilder::getGLSLOutputParameterGroupType(IRType* elementType)
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 05a6fa55c..d24c2d12b 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1574,7 +1574,14 @@ SIMPLE_IR_TYPE(MetalMeshGridPropertiesType, Type)
SIMPLE_IR_TYPE(GLSLInputAttachmentType, Type)
SIMPLE_IR_PARENT_TYPE(ParameterGroupType, PointerLikeType)
-SIMPLE_IR_PARENT_TYPE(UniformParameterGroupType, ParameterGroupType)
+
+struct IRUniformParameterGroupType : IRParameterGroupType
+{
+ IR_PARENT_ISA(UniformParameterGroupType)
+
+ IRType* getDataLayout() { return getOperandCount() > 1 ? (IRType*)getOperand(1) : nullptr; }
+};
+
SIMPLE_IR_PARENT_TYPE(VaryingParameterGroupType, ParameterGroupType)
SIMPLE_IR_TYPE(ConstantBufferType, UniformParameterGroupType)
SIMPLE_IR_TYPE(TextureBufferType, UniformParameterGroupType)
diff --git a/source/slang/slang-legalize-types.cpp b/source/slang/slang-legalize-types.cpp
index 6d827a412..7695ba385 100644
--- a/source/slang/slang-legalize-types.cpp
+++ b/source/slang/slang-legalize-types.cpp
@@ -527,12 +527,25 @@ static IRType* createBuiltinGenericType(
return context->getBuilder()->getType(op, 1, operands);
}
+static IRType* createBuiltinGenericType(
+ TypeLegalizationContext* context,
+ IROp op,
+ IRType* elementType,
+ IRInst* layoutOperand)
+{
+ if (!layoutOperand)
+ return createBuiltinGenericType(context, op, elementType);
+ IRInst* operands[] = {elementType, layoutOperand};
+ return context->getBuilder()->getType(op, 2, operands);
+}
+
// Create a uniform buffer type with a given legalized
// element type.
static LegalType createLegalUniformBufferType(
TypeLegalizationContext* context,
IROp op,
- LegalType legalElementType)
+ LegalType legalElementType,
+ IRInst* layoutOperand)
{
// We will handle some of the easy/non-interesting
// cases here in the main routine, but for all
@@ -543,7 +556,7 @@ static LegalType createLegalUniformBufferType(
switch (legalElementType.flavor)
{
default:
- return context->createLegalUniformBufferType(op, legalElementType);
+ return context->createLegalUniformBufferType(op, legalElementType, layoutOperand);
case LegalType::Flavor::none:
return LegalType();
@@ -558,7 +571,7 @@ static LegalType createLegalUniformBufferType(
// an unlikely case in practice.
//
return LegalType::simple(
- createBuiltinGenericType(context, op, legalElementType.getSimple()));
+ createBuiltinGenericType(context, op, legalElementType.getSimple(), layoutOperand));
}
break;
@@ -581,7 +594,8 @@ static LegalType createLegalUniformBufferType(
return LegalType::implicitDeref(createLegalUniformBufferType(
context,
op,
- legalElementType.getImplicitDeref()->valueType));
+ legalElementType.getImplicitDeref()->valueType,
+ layoutOperand));
}
break;
}
@@ -593,7 +607,8 @@ static LegalType createLegalUniformBufferType(
LegalType createLegalUniformBufferTypeForResources(
TypeLegalizationContext* context,
IROp op,
- LegalType legalElementType)
+ LegalType legalElementType,
+ IRInst* layoutOperand)
{
switch (legalElementType.flavor)
{
@@ -627,7 +642,8 @@ LegalType createLegalUniformBufferTypeForResources(
// buffer with the appropriate `op`, so that case
// is easy:
//
- auto ordinaryType = createLegalUniformBufferType(context, op, pairType->ordinaryType);
+ auto ordinaryType =
+ createLegalUniformBufferType(context, op, pairType->ordinaryType, layoutOperand);
// For the special side, we really just want to turn
// a special field of type `R` into a value of type
@@ -824,7 +840,8 @@ LegalElementWrapping declareStructFields(
LegalType createLegalUniformBufferTypeForExistentials(
TypeLegalizationContext* context,
IROp op,
- LegalType legalElementType)
+ LegalType legalElementType,
+ IRInst* layoutOperand)
{
auto builder = context->getBuilder();
@@ -840,7 +857,7 @@ LegalType createLegalUniformBufferTypeForExistentials(
// (not a `LegalType`) we can go ahead and create an
// IR uniform buffer type that wraps it.
//
- auto bufferType = createBuiltinGenericType(context, op, structType);
+ auto bufferType = createBuiltinGenericType(context, op, structType, layoutOperand);
// The `elementWrapping` computed when we declared all
// the `struct` fields tells us how to get from the
@@ -859,7 +876,11 @@ static LegalType createLegalUniformBufferType(
IRUniformParameterGroupType* uniformBufferType,
LegalType legalElementType)
{
- return createLegalUniformBufferType(context, uniformBufferType->getOp(), legalElementType);
+ return createLegalUniformBufferType(
+ context,
+ uniformBufferType->getOp(),
+ legalElementType,
+ uniformBufferType->getDataLayout());
}
// Create a pointer type with a given legalized value type.
@@ -1141,7 +1162,8 @@ LegalType legalizeTypeImpl(TypeLegalizationContext* context, IRType* type)
//
return context->createLegalUniformBufferType(
uniformBufferType->getOp(),
- legalElementType);
+ legalElementType,
+ uniformBufferType->getDataLayout());
}
}
diff --git a/source/slang/slang-legalize-types.h b/source/slang/slang-legalize-types.h
index f70ac7757..eaee373b2 100644
--- a/source/slang/slang-legalize-types.h
+++ b/source/slang/slang-legalize-types.h
@@ -654,7 +654,10 @@ struct IRTypeLegalizationContext
/// This function will only be called if `legalElementType` is
/// somehow non-trivial.
///
- virtual LegalType createLegalUniformBufferType(IROp op, LegalType legalElementType) = 0;
+ virtual LegalType createLegalUniformBufferType(
+ IROp op,
+ LegalType legalElementType,
+ IRInst* layoutOperand) = 0;
};
// This typedef exists to support pre-existing code from when
@@ -675,7 +678,8 @@ ModuleDecl* findModuleForDecl(Decl* decl);
LegalType createLegalUniformBufferTypeForResources(
TypeLegalizationContext* context,
IROp op,
- LegalType legalElementType);
+ LegalType legalElementType,
+ IRInst* layoutOperand);
/// Create a uniform buffer type suitable for existential legalization.
///
@@ -686,7 +690,8 @@ LegalType createLegalUniformBufferTypeForResources(
LegalType createLegalUniformBufferTypeForExistentials(
TypeLegalizationContext* context,
IROp op,
- LegalType legalElementType);
+ LegalType legalElementType,
+ IRInst* layoutOperand);
void legalizeExistentialTypeLayout(TargetProgram* target, IRModule* module, DiagnosticSink* sink);
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index 3621c6c00..e45eb4652 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -707,7 +707,7 @@ RefPtr<TypeLayout> getTypeLayoutForGlobalShaderParameter(
// If the target doesn't support specialization constants, then we will
// layout them as ordinary uniform data.
specializationConstantRule =
- rules->getConstantBufferRules(context->getTargetRequest()->getOptionSet());
+ rules->getConstantBufferRules(context->getTargetRequest()->getOptionSet(), type);
}
return createTypeLayoutWith(layoutContext, specializationConstantRule, type);
}
@@ -718,7 +718,7 @@ RefPtr<TypeLayout> getTypeLayoutForGlobalShaderParameter(
// shader parameter.
return createTypeLayoutWith(
layoutContext,
- rules->getConstantBufferRules(context->getTargetRequest()->getOptionSet()),
+ rules->getConstantBufferRules(context->getTargetRequest()->getOptionSet(), type),
type);
}
@@ -2421,11 +2421,21 @@ static RefPtr<TypeLayout> computeEntryPointParameterTypeLayout(
// a uniform shader parameter passed via the implicitly-defined
// constant buffer (e.g., the `$Params` constant buffer seen in fxc/dxc output).
//
- return createTypeLayoutWith(
- context->layoutContext,
- context->getRulesFamily()->getConstantBufferRules(
- context->getTargetRequest()->getOptionSet()),
- paramType);
+ LayoutRulesImpl* layoutRules = nullptr;
+ if (isKhronosTarget(context->getTargetRequest()))
+ {
+ // For Vulkan, entry point uniform parameters are laid out using push constant buffer
+ // rules (defaults to std430).
+ layoutRules = context->getRulesFamily()->getShaderStorageBufferRules(
+ context->getTargetProgram()->getOptionSet());
+ }
+ else
+ {
+ layoutRules = context->getRulesFamily()->getConstantBufferRules(
+ context->getTargetRequest()->getOptionSet(),
+ paramType);
+ }
+ return createTypeLayoutWith(context->layoutContext, layoutRules, paramType);
}
else
{
@@ -2783,12 +2793,13 @@ static ParameterBindingAndKindInfo _allocateConstantBufferBinding(ParameterBindi
UInt space = context->shared->defaultSpace;
auto usedRangeSet = _getOrCreateUsedRangeSetForSpace(context, space);
- auto layoutInfo = context->getRulesFamily()
- ->getConstantBufferRules(context->getTargetRequest()->getOptionSet())
- ->GetObjectLayout(
- ShaderParameterKind::ConstantBuffer,
- context->layoutContext.objectLayoutOptions)
- .getSimple();
+ auto layoutInfo =
+ context->getRulesFamily()
+ ->getConstantBufferRules(context->getTargetRequest()->getOptionSet(), nullptr)
+ ->GetObjectLayout(
+ ShaderParameterKind::ConstantBuffer,
+ context->layoutContext.objectLayoutOptions)
+ .getSimple();
ParameterBindingAndKindInfo info;
info.kind = layoutInfo.kind;
@@ -2809,7 +2820,9 @@ static ParameterBindingAndKindInfo _assignConstantBufferBinding(
auto usedRangeSet = _getOrCreateUsedRangeSetForSpace(context, space);
auto layoutInfo = context->getRulesFamily()
- ->getConstantBufferRules(context->getTargetRequest()->getOptionSet())
+ ->getConstantBufferRules(
+ context->getTargetRequest()->getOptionSet(),
+ varLayout->typeLayout ? varLayout->typeLayout->getType() : nullptr)
->GetObjectLayout(
ShaderParameterKind::ConstantBuffer,
context->layoutContext.objectLayoutOptions)
@@ -3786,6 +3799,7 @@ static bool _calcNeedsDefaultSpace(SharedParameterBindingContext& sharedContext)
case LayoutResourceKind::RegisterSpace:
case LayoutResourceKind::SubElementRegisterSpace:
case LayoutResourceKind::PushConstantBuffer:
+ case LayoutResourceKind::SpecializationConstant:
continue;
case LayoutResourceKind::Uniform:
{
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index 589a170fa..9e448a5fa 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -985,6 +985,11 @@ Val* _tryLookupConcreteAssociatedTypeFromThisTypeSubst(ASTBuilder* builder, Decl
return nullptr;
}
+Type* UniformParameterGroupType::getLayoutType()
+{
+ return as<Type>(getGenericArg(getDeclRef(), 1));
+}
+
ModuleDecl* getModuleDecl(Decl* decl)
{
for (auto dd = decl; dd; dd = dd->parentDecl)
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 62caecf72..da4cd458b 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -1022,7 +1022,9 @@ MetalVaryingLayoutRulesImpl kMetalVaryingOutputLayoutRulesImpl(LayoutResourceKin
struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1044,7 +1046,9 @@ struct GLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1066,7 +1070,9 @@ struct HLSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1087,7 +1093,9 @@ struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct CUDALayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1108,7 +1116,9 @@ struct CUDALayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct MetalLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1129,7 +1139,9 @@ struct MetalLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
struct WGSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
virtual LayoutRulesImpl* getPushConstantBufferRules() override;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
virtual LayoutRulesImpl* getVaryingInputRules() override;
@@ -1514,13 +1526,28 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getAnyValueRules()
}
LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules(
- CompilerOptionSet& compilerOptions)
+ CompilerOptionSet& compilerOptions,
+ Type* containerType)
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCConstantBufferLayoutRulesFamilyImpl;
-
+ if (auto cbufferType = as<ConstantBufferType>(containerType))
+ {
+ switch (cbufferType->getLayoutType()->astNodeType)
+ {
+ case ASTNodeType::DefaultDataLayoutType:
+ case ASTNodeType::Std140DataLayoutType:
+ return &kStd140LayoutRulesImpl_;
+ case ASTNodeType::Std430DataLayoutType:
+ return &kStd430LayoutRulesImpl_;
+ case ASTNodeType::ScalarDataLayoutType:
+ return &kScalarLayoutRulesImpl_;
+ default:
+ break;
+ }
+ }
return &kStd140LayoutRulesImpl_;
}
@@ -1615,7 +1642,7 @@ LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getAnyValueRules()
return &kHLSLAnyValueLayoutRulesImpl_;
}
-LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&)
+LayoutRulesImpl* HLSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
{
return &kHLSLConstantBufferLayoutRulesImpl_;
}
@@ -1689,7 +1716,7 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getAnyValueRules()
return &kCPUAnyValueLayoutRulesImpl_;
}
-LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&)
+LayoutRulesImpl* CPULayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
{
return &kCPULayoutRulesImpl_;
}
@@ -1755,7 +1782,7 @@ LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getAnyValueRules()
return &kCUDAAnyValueLayoutRulesImpl_;
}
-LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&)
+LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
{
return &kCUDALayoutRulesImpl_;
}
@@ -1944,7 +1971,7 @@ LayoutRulesImpl* MetalLayoutRulesFamilyImpl::getAnyValueRules()
return &kHLSLAnyValueLayoutRulesImpl_;
}
-LayoutRulesImpl* MetalLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&)
+LayoutRulesImpl* MetalLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
{
return &kMetalConstantBufferLayoutRulesImpl_;
}
@@ -2022,7 +2049,7 @@ LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getAnyValueRules()
return &kGLSLAnyValueLayoutRulesImpl_;
}
-LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&)
+LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
{
return &kWGSLConstantBufferLayoutRulesImpl_;
}
@@ -2178,7 +2205,7 @@ TypeLayoutContext getInitialLayoutContextForTarget(
if (rulesFamily)
{
- context.rules = rulesFamily->getConstantBufferRules(targetReq->getOptionSet());
+ context.rules = rulesFamily->getConstantBufferRules(targetReq->getOptionSet(), nullptr);
}
return context;
@@ -3438,7 +3465,9 @@ LayoutRulesImpl* getParameterBufferElementTypeLayoutRules(
{
if (as<ConstantBufferType>(parameterGroupType))
{
- return rules->getLayoutRulesFamily()->getConstantBufferRules(compilerOptions);
+ return rules->getLayoutRulesFamily()->getConstantBufferRules(
+ compilerOptions,
+ parameterGroupType);
}
else if (as<TextureBufferType>(parameterGroupType))
{
diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h
index 87d9123ff..2cdb4b386 100644
--- a/source/slang/slang-type-layout.h
+++ b/source/slang/slang-type-layout.h
@@ -1105,7 +1105,9 @@ struct LayoutRulesImpl
struct LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() = 0;
- virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) = 0;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) = 0;
virtual LayoutRulesImpl* getPushConstantBufferRules() = 0;
virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) = 0;
virtual LayoutRulesImpl* getVaryingInputRules() = 0;
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 854d90df5..e4de61276 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1608,7 +1608,9 @@ SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL Linkage::getContainerType(
{
case slang::ContainerType::ConstantBuffer:
{
- ConstantBufferType* cbType = getASTBuilder()->getConstantBufferType(type);
+ SemanticsVisitor visitor(getSemanticsForReflection());
+ auto layoutType = getASTBuilder()->getDefaultLayoutType();
+ Type* cbType = visitor.getConstantBufferType(type, layoutType);
containerTypeReflection = cbType;
}
break;