summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-layout.cpp
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-08-21 08:47:18 +0300
committerGitHub <noreply@github.com>2025-08-21 05:47:18 +0000
commit35f8e092f2aa3ed5e3cf03387e712f798ff4850e (patch)
treebdafc75e4df90157568758ebf7b8128ecd066f0c /source/slang/slang-ir-layout.cpp
parent05f0f5603561daed2c134e13bc64649362759968 (diff)
Introduce CDataLayout & -fvk-use-c-layout (#8136)
Closes #8112. ~~The issue asks for a "C layout", but in this PR I use the term "CPU layout" because this naming was pre-existing in the codebase as `kCPULayoutRulesImpl_`. The primary purpose of this layout is to match CPU-side struct definitions with the shader side. I'm open to better naming suggestions, though.~~ Edit: switched back to using `CDataLayout` & `-fvk-use-c-layout`, as the CPU target depends on the object layout rules of existing CPU layout rules, but they're incompatible with actual shaders. So a new `kCLayoutRulesImpl_` was needed anyway. --------- Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-layout.cpp')
-rw-r--r--source/slang/slang-ir-layout.cpp105
1 files changed, 74 insertions, 31 deletions
diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp
index ac0c79601..d3b86a1c6 100644
--- a/source/slang/slang-ir-layout.cpp
+++ b/source/slang/slang-ir-layout.cpp
@@ -83,9 +83,8 @@ IRIntegerValue getIntegerValueFromInst(IRInst* inst)
return as<IRIntLit>(inst)->value.intVal;
}
-static Result _calcSizeAndAlignment(
+Result IRTypeLayoutRules::calcSizeAndAlignment(
CompilerOptionSet& optionSet,
- IRTypeLayoutRules* rules,
IRType* type,
IRSizeAndAlignment* outSizeAndAlignment)
{
@@ -131,10 +130,6 @@ static Result _calcSizeAndAlignment(
// We are currently handling `bool` following the HLSL
// precednet of storing it in 4 bytes.
//
- // TODO: It would be good to try to make this follow
- // per-platform conventions, or at least to be able
- // to use a 1-byte encoding where available.
- //
BASE(Bool, 4);
// The Slang `void` type is treated as a zero-byte
@@ -142,7 +137,7 @@ static Result _calcSizeAndAlignment(
//
CASE(Void, 0, 1);
-#undef CASE
+#undef BASE
#undef CASE
@@ -163,7 +158,7 @@ static Result _calcSizeAndAlignment(
IRSizeAndAlignment fieldTypeLayout;
SLANG_RETURN_ON_FAIL(
- getSizeAndAlignment(optionSet, rules, field->getFieldType(), &fieldTypeLayout));
+ getSizeAndAlignment(optionSet, this, field->getFieldType(), &fieldTypeLayout));
seenFinalUnsizedArrayField =
fieldTypeLayout.size == IRSizeAndAlignment::kIndeterminateSize;
@@ -174,7 +169,7 @@ static Result _calcSizeAndAlignment(
}
else
{
- offset = rules->adjustOffset(
+ offset = adjustOffset(
offset,
fieldTypeLayout.size,
lastFieldType,
@@ -199,7 +194,7 @@ static Result _calcSizeAndAlignment(
builder.addDecoration(
field,
kIROp_OffsetDecoration,
- builder.getIntValue(intType, (IRIntegerValue)rules->ruleName),
+ builder.getIntValue(intType, (IRIntegerValue)ruleName),
builder.getIntValue(intType, fieldOffset));
}
if (!seenFinalUnsizedArrayField)
@@ -208,7 +203,7 @@ static Result _calcSizeAndAlignment(
lastFieldType = field->getFieldType();
lastFieldAlignment = fieldTypeLayout.alignment;
}
- *outSizeAndAlignment = rules->alignCompositeElement(structLayout);
+ *outSizeAndAlignment = alignCompositeElement(structLayout);
return SLANG_OK;
}
break;
@@ -219,7 +214,7 @@ static Result _calcSizeAndAlignment(
return _calcArraySizeAndAlignment(
optionSet,
- rules,
+ this,
arrayType->getElementType(),
arrayType->getElementCount(),
outSizeAndAlignment);
@@ -229,11 +224,7 @@ static Result _calcSizeAndAlignment(
case kIROp_AtomicType:
{
auto atomicType = cast<IRAtomicType>(type);
- _calcSizeAndAlignment(
- optionSet,
- rules,
- atomicType->getElementType(),
- outSizeAndAlignment);
+ calcSizeAndAlignment(optionSet, atomicType->getElementType(), outSizeAndAlignment);
return SLANG_OK;
}
break;
@@ -243,7 +234,7 @@ static Result _calcSizeAndAlignment(
auto unsizedArrayType = cast<IRUnsizedArrayType>(type);
getSizeAndAlignment(
optionSet,
- rules,
+ this,
unsizedArrayType->getElementType(),
outSizeAndAlignment);
outSizeAndAlignment->size = IRSizeAndAlignment::kIndeterminateSize;
@@ -255,8 +246,8 @@ static Result _calcSizeAndAlignment(
{
auto vecType = cast<IRVectorType>(type);
IRSizeAndAlignment elementTypeLayout;
- getSizeAndAlignment(optionSet, rules, vecType->getElementType(), &elementTypeLayout);
- *outSizeAndAlignment = rules->getVectorSizeAndAlignment(
+ getSizeAndAlignment(optionSet, this, vecType->getElementType(), &elementTypeLayout);
+ *outSizeAndAlignment = getVectorSizeAndAlignment(
elementTypeLayout,
getIntegerValueFromInst(vecType->getElementCount()));
return SLANG_OK;
@@ -267,7 +258,7 @@ static Result _calcSizeAndAlignment(
auto anyValType = cast<IRAnyValueType>(type);
outSizeAndAlignment->size = getIntVal(anyValType->getSize());
outSizeAndAlignment->alignment = 4;
- *outSizeAndAlignment = rules->alignCompositeElement(*outSizeAndAlignment);
+ *outSizeAndAlignment = alignCompositeElement(*outSizeAndAlignment);
return SLANG_OK;
}
break;
@@ -282,8 +273,8 @@ static Result _calcSizeAndAlignment(
auto elementType = tupleType->getOperand(i);
IRSizeAndAlignment fieldTypeLayout;
SLANG_RETURN_ON_FAIL(
- getSizeAndAlignment(optionSet, rules, (IRType*)elementType, &fieldTypeLayout));
- resultLayout.size = rules->adjustOffset(
+ getSizeAndAlignment(optionSet, this, (IRType*)elementType, &fieldTypeLayout));
+ resultLayout.size = adjustOffset(
resultLayout.size,
fieldTypeLayout.size,
lastFieldType,
@@ -296,7 +287,7 @@ static Result _calcSizeAndAlignment(
lastFieldType = as<IRType>(elementType);
lastFieldAlignment = fieldTypeLayout.alignment;
}
- *outSizeAndAlignment = rules->alignCompositeElement(resultLayout);
+ *outSizeAndAlignment = alignCompositeElement(resultLayout);
return SLANG_OK;
}
break;
@@ -320,7 +311,7 @@ static Result _calcSizeAndAlignment(
IRSizeAndAlignment resultLayout;
resultLayout.size = size;
resultLayout.alignment = 4;
- *outSizeAndAlignment = rules->alignCompositeElement(resultLayout);
+ *outSizeAndAlignment = alignCompositeElement(resultLayout);
return SLANG_OK;
}
break;
@@ -334,7 +325,7 @@ static Result _calcSizeAndAlignment(
builder.getVectorType(matType->getElementType(), matType->getRowCount());
return _calcArraySizeAndAlignment(
optionSet,
- rules,
+ this,
colVector,
matType->getColumnCount(),
outSizeAndAlignment);
@@ -345,7 +336,7 @@ static Result _calcSizeAndAlignment(
builder.getVectorType(matType->getElementType(), matType->getColumnCount());
return _calcArraySizeAndAlignment(
optionSet,
- rules,
+ this,
rowVector,
matType->getRowCount(),
outSizeAndAlignment);
@@ -369,6 +360,7 @@ static Result _calcSizeAndAlignment(
}
break;
case kIROp_ScalarBufferLayoutType:
+ case kIROp_CBufferLayoutType:
case kIROp_Std140BufferLayoutType:
case kIROp_Std430BufferLayoutType:
case kIROp_DefaultBufferLayoutType:
@@ -380,7 +372,7 @@ static Result _calcSizeAndAlignment(
builder.setInsertBefore(type);
auto uintType = builder.getUIntType();
auto uint2Type = builder.getVectorType(uintType, 2);
- return getSizeAndAlignment(optionSet, rules, uint2Type, outSizeAndAlignment);
+ return getSizeAndAlignment(optionSet, this, uint2Type, outSizeAndAlignment);
}
case kIROp_AttributedType:
{
@@ -388,7 +380,7 @@ static Result _calcSizeAndAlignment(
SLANG_ASSERT(attributedType->getAttr()->getOp() == kIROp_NoDiffAttr);
return getSizeAndAlignment(
optionSet,
- rules,
+ this,
attributedType->getBaseType(),
outSizeAndAlignment);
}
@@ -396,7 +388,7 @@ static Result _calcSizeAndAlignment(
{
auto enumType = cast<IREnumType>(type);
auto tagType = enumType->getTagType();
- return _calcSizeAndAlignment(optionSet, rules, tagType, outSizeAndAlignment);
+ return calcSizeAndAlignment(optionSet, tagType, outSizeAndAlignment);
}
break;
default:
@@ -439,7 +431,7 @@ Result getSizeAndAlignment(
}
IRSizeAndAlignment sizeAndAlignment;
- SLANG_RETURN_ON_FAIL(_calcSizeAndAlignment(optionSet, rules, type, &sizeAndAlignment));
+ SLANG_RETURN_ON_FAIL(rules->calcSizeAndAlignment(optionSet, type, &sizeAndAlignment));
if (auto module = type->getModule())
{
@@ -538,6 +530,49 @@ struct NaturalLayoutRules : IRTypeLayoutRules
}
};
+struct CLayoutRules : IRTypeLayoutRules
+{
+ CLayoutRules() { ruleName = IRTypeLayoutRuleName::C; }
+
+ virtual Result calcSizeAndAlignment(
+ CompilerOptionSet& optionSet,
+ IRType* type,
+ IRSizeAndAlignment* outSizeAndAlignment)
+ {
+ if (type->getOp() == kIROp_BoolType)
+ {
+ *outSizeAndAlignment = IRSizeAndAlignment(1, 1);
+ return SLANG_OK;
+ }
+ return IRTypeLayoutRules::calcSizeAndAlignment(optionSet, type, outSizeAndAlignment);
+ }
+
+ virtual IRIntegerValue adjustOffset(
+ IRIntegerValue offset,
+ IRIntegerValue elementSize,
+ IRType* lastFieldType,
+ IRIntegerValue lastFieldAlignment)
+ {
+ SLANG_UNUSED(elementSize);
+ SLANG_UNUSED(lastFieldType);
+ return align(offset, (int)lastFieldAlignment);
+ }
+
+ virtual IRSizeAndAlignment alignCompositeElement(IRSizeAndAlignment elementSize)
+ {
+ IRSizeAndAlignment alignedSize = elementSize;
+ alignedSize.size = align(alignedSize.size, alignedSize.alignment);
+ return alignedSize;
+ }
+
+ virtual IRSizeAndAlignment getVectorSizeAndAlignment(
+ IRSizeAndAlignment element,
+ IRIntegerValue count)
+ {
+ return IRSizeAndAlignment(element.size * count, element.alignment);
+ }
+};
+
struct ConstantBufferLayoutRules : IRTypeLayoutRules
{
ConstantBufferLayoutRules() { ruleName = IRTypeLayoutRuleName::D3DConstantBuffer; }
@@ -713,6 +748,12 @@ IRTypeLayoutRules* IRTypeLayoutRules::getNatural()
return &rules;
}
+IRTypeLayoutRules* IRTypeLayoutRules::getC()
+{
+ static CLayoutRules rules;
+ return &rules;
+}
+
IRTypeLayoutRules* IRTypeLayoutRules::getConstantBuffer()
{
static ConstantBufferLayoutRules rules;
@@ -729,6 +770,8 @@ IRTypeLayoutRules* IRTypeLayoutRules::get(IRTypeLayoutRuleName name)
return getStd140();
case IRTypeLayoutRuleName::Natural:
return getNatural();
+ case IRTypeLayoutRuleName::C:
+ return getC();
case IRTypeLayoutRuleName::D3DConstantBuffer:
return getConstantBuffer();
default: