summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/hlsl.meta.slang7
-rw-r--r--source/slang/slang-ast-builder.cpp5
-rw-r--r--source/slang/slang-ast-builder.h1
-rw-r--r--source/slang/slang-ast-type.h6
-rw-r--r--source/slang/slang-compiler-options.cpp1
-rw-r--r--source/slang/slang-compiler-options.h2
-rw-r--r--source/slang/slang-emit-spirv.cpp20
-rw-r--r--source/slang/slang-end-to-end-request.cpp5
-rw-r--r--source/slang/slang-end-to-end-request.h2
-rw-r--r--source/slang/slang-ir-entry-point-uniforms.cpp3
-rw-r--r--source/slang/slang-ir-insts-stable-names.lua1
-rw-r--r--source/slang/slang-ir-insts.lua1
-rw-r--r--source/slang/slang-ir-layout.cpp105
-rw-r--r--source/slang/slang-ir-layout.h7
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp29
-rw-r--r--source/slang/slang-ir.h1
-rw-r--r--source/slang/slang-options.cpp16
-rw-r--r--source/slang/slang-type-layout.cpp163
18 files changed, 339 insertions, 36 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 7f8488236..0dbca2479 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -57,6 +57,13 @@ __magic_type(ScalarDataLayoutType)
struct ScalarDataLayout : IBufferDataLayout
{};
+/// @category misc_types
+__intrinsic_type($(kIROp_CBufferLayoutType))
+__magic_type(CDataLayoutType)
+[require(spirv)]
+struct CDataLayout : IBufferDataLayout
+{};
+
//@hidden:
__generic<T, L : IBufferDataLayout = DefaultDataLayout>
__intrinsic_type($(kIROp_GLSLShaderStorageBufferType))
diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp
index d576ed0fb..a71abf570 100644
--- a/source/slang/slang-ast-builder.cpp
+++ b/source/slang/slang-ast-builder.cpp
@@ -489,6 +489,11 @@ Type* ASTBuilder::getScalarLayoutType()
return getSpecializedBuiltinType({}, "ScalarDataLayoutType");
}
+Type* ASTBuilder::getCLayoutType()
+{
+ return getSpecializedBuiltinType({}, "CDataLayoutType");
+}
+
// Construct the type `Out<valueType>`
OutType* ASTBuilder::getOutType(Type* valueType)
{
diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h
index 72f875f91..798e1ddc0 100644
--- a/source/slang/slang-ast-builder.h
+++ b/source/slang/slang-ast-builder.h
@@ -517,6 +517,7 @@ public:
Type* getStd140LayoutType();
Type* getStd430LayoutType();
Type* getScalarLayoutType();
+ Type* getCLayoutType();
Type* getInitializerListType() { return m_sharedASTBuilder->getInitializerListType(); }
Type* getOverloadedType() { return m_sharedASTBuilder->getOverloadedType(); }
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index d262f1ad5..842af8b88 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -162,6 +162,12 @@ class ScalarDataLayoutType : public DataLayoutType
};
FIDDLE()
+class CDataLayoutType : public DataLayoutType
+{
+ FIDDLE(...)
+};
+
+FIDDLE()
class FeedbackType : public BuiltinType
{
FIDDLE(...)
diff --git a/source/slang/slang-compiler-options.cpp b/source/slang/slang-compiler-options.cpp
index 843e0e7cb..fa2b99b98 100644
--- a/source/slang/slang-compiler-options.cpp
+++ b/source/slang/slang-compiler-options.cpp
@@ -143,6 +143,7 @@ void CompilerOptionSet::writeCommandLineArgs(Session* globalSession, StringBuild
case CompilerOptionName::EmitSpirvDirectly:
case CompilerOptionName::GLSLForceScalarLayout:
case CompilerOptionName::ForceDXLayout:
+ case CompilerOptionName::ForceCLayout:
case CompilerOptionName::MatrixLayoutRow:
case CompilerOptionName::MatrixLayoutColumn:
case CompilerOptionName::VulkanInvertY:
diff --git a/source/slang/slang-compiler-options.h b/source/slang/slang-compiler-options.h
index 5986c4e82..ec9383e08 100644
--- a/source/slang/slang-compiler-options.h
+++ b/source/slang/slang-compiler-options.h
@@ -348,6 +348,8 @@ struct CompilerOptionSet
bool shouldUseDXLayout() { return getBoolOption(CompilerOptionName::ForceDXLayout); }
+ bool shouldUseCLayout() { return getBoolOption(CompilerOptionName::ForceCLayout); }
+
bool shouldDumpIntermediates() { return getBoolOption(CompilerOptionName::DumpIntermediates); }
bool shouldDumpIR() { return getBoolOption(CompilerOptionName::DumpIr); }
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 6b42896d0..d6f4ac176 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1847,10 +1847,22 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
IRSizeAndAlignment sizeAndAlignment;
uint32_t stride;
- getNaturalSizeAndAlignment(
- m_targetProgram->getOptionSet(),
- valueType,
- &sizeAndAlignment);
+ if (auto layout = valueType->findDecoration<IRSizeAndAlignmentDecoration>())
+ {
+ auto rule = IRTypeLayoutRules::get(layout->getLayoutName());
+ getSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ rule,
+ valueType,
+ &sizeAndAlignment);
+ }
+ else
+ {
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ valueType,
+ &sizeAndAlignment);
+ }
uint64_t valueSize = sizeAndAlignment.size;
// Any unsized data type (e.g. struct or array) will have size of
diff --git a/source/slang/slang-end-to-end-request.cpp b/source/slang/slang-end-to-end-request.cpp
index 725fc1854..fc2d6d55e 100644
--- a/source/slang/slang-end-to-end-request.cpp
+++ b/source/slang/slang-end-to-end-request.cpp
@@ -894,6 +894,11 @@ void EndToEndCompileRequest::setTargetForceDXLayout(int targetIndex, bool value)
getTargetOptionSet(targetIndex).set(CompilerOptionName::ForceDXLayout, value);
}
+void EndToEndCompileRequest::setTargetForceCLayout(int targetIndex, bool value)
+{
+ getTargetOptionSet(targetIndex).set(CompilerOptionName::ForceCLayout, value);
+}
+
void EndToEndCompileRequest::setTargetFloatingPointMode(
int targetIndex,
SlangFloatingPointMode mode)
diff --git a/source/slang/slang-end-to-end-request.h b/source/slang/slang-end-to-end-request.h
index af04eac63..f8d666970 100644
--- a/source/slang/slang-end-to-end-request.h
+++ b/source/slang/slang-end-to-end-request.h
@@ -100,6 +100,8 @@ public:
setTargetGenerateWholeProgram(int targetIndex, bool value) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setTargetEmbedDownstreamIR(int targetIndex, bool value)
SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW void SLANG_MCALL setTargetForceCLayout(int targetIndex, bool value)
+ SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setMatrixLayoutMode(SlangMatrixLayoutMode mode)
SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoLevel(SlangDebugInfoLevel level)
diff --git a/source/slang/slang-ir-entry-point-uniforms.cpp b/source/slang/slang-ir-entry-point-uniforms.cpp
index 586d64b4f..e75be9e24 100644
--- a/source/slang/slang-ir-entry-point-uniforms.cpp
+++ b/source/slang/slang-ir-entry-point-uniforms.cpp
@@ -557,6 +557,9 @@ struct CollectEntryPointUniformParams : PerEntryPointPass
if (m_options.targetReq->getOptionSet().getBoolOption(
CompilerOptionName::GLSLForceScalarLayout))
layoutType = builder.getType(kIROp_ScalarBufferLayoutType);
+ else if (m_options.targetReq->getOptionSet().getBoolOption(
+ CompilerOptionName::ForceCLayout))
+ layoutType = builder.getType(kIROp_CBufferLayoutType);
else if (isKhronosTarget(m_options.targetReq))
layoutType = builder.getType(kIROp_Std430BufferLayoutType);
else
diff --git a/source/slang/slang-ir-insts-stable-names.lua b/source/slang/slang-ir-insts-stable-names.lua
index db2a8f8c8..589c4b130 100644
--- a/source/slang/slang-ir-insts-stable-names.lua
+++ b/source/slang/slang-ir-insts-stable-names.lua
@@ -669,4 +669,5 @@ return {
["SPIRVAsmOperand.__sampledType"] = 665,
["SPIRVAsmOperand.__imageType"] = 666,
["SPIRVAsmOperand.__sampledImageType"] = 667,
+ ["Type.CLayout"] = 668,
}
diff --git a/source/slang/slang-ir-insts.lua b/source/slang/slang-ir-insts.lua
index 0325fcbfd..c1777c2cf 100644
--- a/source/slang/slang-ir-insts.lua
+++ b/source/slang/slang-ir-insts.lua
@@ -206,6 +206,7 @@ local insts = {
{ Std140Layout = { struct_name = "Std140BufferLayoutType", hoistable = true } },
{ Std430Layout = { struct_name = "Std430BufferLayoutType", hoistable = true } },
{ ScalarLayout = { struct_name = "ScalarBufferLayoutType", hoistable = true } },
+ { CLayout = { struct_name = "CBufferLayoutType", hoistable = true } },
{ SubpassInputType = { operands = { { "elementType", "IRType" }, { "isMultisampleInst" } }, hoistable = true } },
{ TextureFootprintType = { min_operands = 1, hoistable = true } },
{ TextureShape1DType = { hoistable = true } },
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:
diff --git a/source/slang/slang-ir-layout.h b/source/slang/slang-ir-layout.h
index 1918f31b6..a0f144c86 100644
--- a/source/slang/slang-ir-layout.h
+++ b/source/slang/slang-ir-layout.h
@@ -56,6 +56,12 @@ struct IRTypeLayoutRules
public:
IRTypeLayoutRuleName ruleName;
+ /// This function calculates the size and alignment of the given type.
+ virtual Result calcSizeAndAlignment(
+ CompilerOptionSet& optionSet,
+ IRType* type,
+ IRSizeAndAlignment* outSizeAndAlignment);
+
/// Align composite based on rule. Type is aligned assuming
/// it is apart of a composite (array, struct, matrix, etc...)
virtual IRSizeAndAlignment alignCompositeElement(IRSizeAndAlignment elementSize) = 0;
@@ -79,6 +85,7 @@ public:
static IRTypeLayoutRules* getStd430();
static IRTypeLayoutRules* getStd140();
static IRTypeLayoutRules* getNatural();
+ static IRTypeLayoutRules* getC();
static IRTypeLayoutRules* getConstantBuffer();
static IRTypeLayoutRules* get(IRTypeLayoutRuleName name);
};
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp
index ed0a3b309..2f40c6cf9 100644
--- a/source/slang/slang-ir-lower-buffer-element-type.cpp
+++ b/source/slang/slang-ir-lower-buffer-element-type.cpp
@@ -426,6 +426,8 @@ struct LoweredElementTypeContext
return "std430";
case IRTypeLayoutRuleName::Natural:
return "natural";
+ case IRTypeLayoutRuleName::C:
+ return "c";
default:
return "default";
}
@@ -797,7 +799,26 @@ struct LoweredElementTypeContext
if (as<IRBoolType>(scalarType))
{
// Bool is an abstract type in SPIRV, so we need to lower them into an int.
- info.loweredType = builder.getIntType();
+
+ // Find an integer type of the correct size for the current layout rule.
+ IRSizeAndAlignment boolSizeAndAlignment;
+ if (getSizeAndAlignment(
+ target->getOptionSet(),
+ config.layoutRule,
+ scalarType,
+ &boolSizeAndAlignment) == SLANG_OK)
+ {
+ IntInfo ii;
+ ii.width = boolSizeAndAlignment.size * 8;
+ ii.isSigned = true;
+ info.loweredType = builder.getType(getIntTypeOpFromInfo(ii));
+ }
+ else
+ {
+ // Just in case that fails for some reason, just use an int.
+ info.loweredType = builder.getIntType();
+ }
+
if (vectorType)
info.loweredType = builder.getVectorType(
info.loweredType,
@@ -1467,6 +1488,8 @@ IRTypeLayoutRules* getTypeLayoutRulesFromOp(IROp layoutTypeOp, IRTypeLayoutRules
return IRTypeLayoutRules::getStd430();
case kIROp_ScalarBufferLayoutType:
return IRTypeLayoutRules::getNatural();
+ case kIROp_CBufferLayoutType:
+ return IRTypeLayoutRules::getC();
}
return defaultLayout;
}
@@ -1482,6 +1505,10 @@ IRTypeLayoutRules* getTypeLayoutRuleForBuffer(TargetProgram* target, IRType* buf
if (!target->shouldEmitSPIRVDirectly())
return IRTypeLayoutRules::getNatural();
+ // If the user specified a C-compatible buffer layout, then do that.
+ if (target->getOptionSet().shouldUseCLayout())
+ return IRTypeLayoutRules::getC();
+
// If the user specified a scalar buffer layout, then just use that.
if (target->getOptionSet().shouldUseScalarLayout())
return IRTypeLayoutRules::getNatural();
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 1f6418036..ad14edf21 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -524,6 +524,7 @@ enum class IRTypeLayoutRuleName
Std430,
Std140,
D3DConstantBuffer,
+ C,
_Count,
};
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index b0eb1748d..2115a096f 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -663,6 +663,12 @@ void initCommandOptions(CommandOptions& options)
"-fvk-use-dx-layout",
nullptr,
"Pack members using FXCs member packing rules when targeting GLSL or SPIRV."},
+ {OptionKind::ForceCLayout,
+ "-fvk-use-c-layout",
+ nullptr,
+ "Make data accessed through ConstantBuffer, ParameterBlock, StructuredBuffer, "
+ "ByteAddressBuffer and general pointers follow the C/C++ structure layout rules "
+ "when targeting SPIRV."},
{OptionKind::VulkanBindShift,
vkShiftNames.getBuffer(),
"-fvk-<vulkan-shift>-shift <N> <space>",
@@ -2670,6 +2676,11 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv)
getCurrentTarget()->optionSet.add(CompilerOptionName::ForceDXLayout, true);
break;
}
+ case OptionKind::ForceCLayout:
+ {
+ getCurrentTarget()->optionSet.add(CompilerOptionName::ForceCLayout, true);
+ break;
+ }
case OptionKind::EnableEffectAnnotations:
{
m_compileRequest->setEnableEffectAnnotations(true);
@@ -3707,6 +3718,11 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv)
m_compileRequest->setTargetForceDXLayout(targetID, true);
}
+ if (rawTarget.optionSet.shouldUseCLayout())
+ {
+ m_compileRequest->setTargetForceCLayout(targetID, true);
+ }
+
if (rawTarget.optionSet.getBoolOption(CompilerOptionName::GenerateWholeProgram))
{
m_compileRequest->setTargetGenerateWholeProgram(targetID, true);
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index 275a178d0..3e2560755 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -1090,6 +1090,29 @@ struct CPULayoutRulesFamilyImpl : LayoutRulesFamilyImpl
LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override;
};
+struct CLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
+{
+ virtual LayoutRulesImpl* getAnyValueRules() override;
+ virtual LayoutRulesImpl* getConstantBufferRules(
+ CompilerOptionSet& compilerOptions,
+ Type* containerType) override;
+ virtual LayoutRulesImpl* getPushConstantBufferRules() override;
+ virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getVaryingInputRules() override;
+ virtual LayoutRulesImpl* getVaryingOutputRules() override;
+ virtual LayoutRulesImpl* getSpecializationConstantRules() override;
+ virtual LayoutRulesImpl* getShaderStorageBufferRules(
+ CompilerOptionSet& compilerOptions) override;
+ virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override;
+
+ LayoutRulesImpl* getRayPayloadParameterRules() override;
+ LayoutRulesImpl* getCallablePayloadParameterRules() override;
+ LayoutRulesImpl* getHitAttributesParameterRules() override;
+
+ LayoutRulesImpl* getShaderRecordConstantBufferRules() override;
+ LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override;
+};
+
struct CUDALayoutRulesFamilyImpl : LayoutRulesFamilyImpl
{
virtual LayoutRulesImpl* getAnyValueRules() override;
@@ -1170,6 +1193,7 @@ struct WGSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl
GLSLLayoutRulesFamilyImpl kGLSLLayoutRulesFamilyImpl;
HLSLLayoutRulesFamilyImpl kHLSLLayoutRulesFamilyImpl;
CPULayoutRulesFamilyImpl kCPULayoutRulesFamilyImpl;
+CLayoutRulesFamilyImpl kCLayoutRulesFamilyImpl;
CUDALayoutRulesFamilyImpl kCUDALayoutRulesFamilyImpl;
MetalLayoutRulesFamilyImpl kMetalLayoutRulesFamilyImpl;
MetalArgumentBufferTier2LayoutRulesFamilyImpl kMetalArgumentBufferTier2LayoutRulesFamilyImpl;
@@ -1341,6 +1365,69 @@ LayoutRulesImpl kCPUAnyValueLayoutRulesImpl_ = {
&kCPUObjectLayoutRulesImpl,
};
+// C layout
+
+LayoutRulesImpl kCLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kCPULayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCAnyValueLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kDefaultLayoutRulesImpl,
+ &kCPUObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCPushConstantRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kCPULayoutRulesImpl,
+ &kGLSLPushConstantBufferObjectLayoutRulesImpl_,
+};
+
+LayoutRulesImpl kCVaryingInputLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLVaryingOutputLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCVaryingOutputLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLVaryingOutputLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCSpecializationConstantLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLSpecializationConstantLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCShaderRecordLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kCPULayoutRulesImpl,
+ &kGLSLShaderRecordConstantBufferObjectLayoutRulesImpl_,
+};
+
+LayoutRulesImpl kCRayPayloadParameterLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLRayPayloadParameterLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCCallablePayloadParameterLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLCallablePayloadParameterLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+LayoutRulesImpl kCHitAttributesParameterLayoutRulesImpl_ = {
+ &kCLayoutRulesFamilyImpl,
+ &kGLSLHitAttributesParameterLayoutRulesImpl,
+ &kGLSLObjectLayoutRulesImpl,
+};
+
+
// CUDA
static CUDAObjectLayoutRulesImpl kCUDAObjectLayoutRulesImpl;
@@ -1534,6 +1621,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules(
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
+ else if (compilerOptions.shouldUseCLayout())
+ return &kCLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCConstantBufferLayoutRulesFamilyImpl;
if (auto cbufferType = as<ConstantBufferType>(containerType))
@@ -1548,6 +1637,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getConstantBufferRules(
return &kStd430LayoutRulesImpl_;
case ASTNodeType::ScalarDataLayoutType:
return &kScalarLayoutRulesImpl_;
+ case ASTNodeType::CDataLayoutType:
+ return &kCLayoutRulesImpl_;
default:
break;
}
@@ -1560,6 +1651,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getParameterBlockRules(
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
+ else if (compilerOptions.shouldUseCLayout())
+ return &kCLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCConstantBufferLayoutRulesFamilyImpl;
@@ -1581,6 +1674,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getTextureBufferRules(
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
+ else if (compilerOptions.shouldUseCLayout())
+ return &kCLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCConstantBufferLayoutRulesFamilyImpl;
@@ -1607,6 +1702,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
+ else if (compilerOptions.shouldUseCLayout())
+ return &kCLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCShaderResourceLayoutRulesFamilyImpl;
@@ -1633,6 +1730,8 @@ LayoutRulesImpl* GLSLLayoutRulesFamilyImpl::getStructuredBufferRules(
{
if (compilerOptions.shouldUseScalarLayout())
return &kScalarLayoutRulesImpl_;
+ else if (compilerOptions.shouldUseCLayout())
+ return &kCLayoutRulesImpl_;
else if (compilerOptions.shouldUseDXLayout())
return &kFXCShaderResourceLayoutRulesFamilyImpl;
@@ -1779,6 +1878,70 @@ LayoutRulesImpl* CPULayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOpti
return &kCPULayoutRulesImpl_;
}
+// C compatible layout family
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getAnyValueRules()
+{
+ return &kCAnyValueLayoutRulesImpl_;
+}
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&, Type*)
+{
+ return &kCLayoutRulesImpl_;
+}
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getPushConstantBufferRules()
+{
+ return &kCPushConstantRulesImpl_;
+}
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getTextureBufferRules(CompilerOptionSet&)
+{
+ return &kCLayoutRulesImpl_;
+}
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getVaryingInputRules()
+{
+ return &kCVaryingInputLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getVaryingOutputRules()
+{
+ return &kCVaryingOutputLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getSpecializationConstantRules()
+{
+ return &kCSpecializationConstantLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet&)
+{
+ return &kCLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet&)
+{
+ return &kCLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getRayPayloadParameterRules()
+{
+ return &kCRayPayloadParameterLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getCallablePayloadParameterRules()
+{
+ return &kCCallablePayloadParameterLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getHitAttributesParameterRules()
+{
+ return &kCHitAttributesParameterLayoutRulesImpl_;
+}
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getShaderRecordConstantBufferRules()
+{
+ return &kCShaderRecordLayoutRulesImpl_;
+}
+
+LayoutRulesImpl* CLayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet&)
+{
+ return &kCLayoutRulesImpl_;
+}
+
// CUDA Family
LayoutRulesImpl* CUDALayoutRulesFamilyImpl::getAnyValueRules()