diff options
| author | Yong He <yonghe@outlook.com> | 2023-08-16 22:47:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-17 13:47:35 +0800 |
| commit | 216fc18661fd6e05053b4cc864396e6017e85b04 (patch) | |
| tree | 48dfd4aef767694f3063d3c79bcc0a1e3c184346 /source/slang/slang-ir-layout.cpp | |
| parent | a0ee2bf671d61d1e2b561db3966e57ffc802040f (diff) | |
Create storage types of different layouts for SPIRV emit. (#3116)
* Create storage types of different layouts for SPIRV emit.
* Fix.
* Fix.
* Fix.
* Update expected failure list.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-layout.cpp')
| -rw-r--r-- | source/slang/slang-ir-layout.cpp | 561 |
1 files changed, 194 insertions, 367 deletions
diff --git a/source/slang/slang-ir-layout.cpp b/source/slang/slang-ir-layout.cpp index df2f50b30..244ff2039 100644 --- a/source/slang/slang-ir-layout.cpp +++ b/source/slang/slang-ir-layout.cpp @@ -50,31 +50,29 @@ namespace Slang { - -static Result _calcNaturalArraySizeAndAlignment( - TargetRequest* target, - IRType* elementType, - IRInst* elementCountInst, +static Result _calcArraySizeAndAlignment( + IRTypeLayoutRules* rules, + IRType* elementType, + IRInst* elementCountInst, IRSizeAndAlignment* outSizeAndAlignment) { auto elementCountLit = as<IRIntLit>(elementCountInst); - if(!elementCountLit) + if (!elementCountLit) return SLANG_FAIL; auto elementCount = elementCountLit->getValue(); - if( elementCount == 0 ) + if (elementCount == 0) { *outSizeAndAlignment = IRSizeAndAlignment(0, 1); return SLANG_OK; } IRSizeAndAlignment elementTypeLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(target, elementType, &elementTypeLayout)); - - auto elementStride = elementTypeLayout.getStride(); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(rules, elementType, &elementTypeLayout)); + elementTypeLayout = rules->alignCompositeElement(elementTypeLayout); *outSizeAndAlignment = IRSizeAndAlignment( - elementStride * (elementCount - 1) + elementTypeLayout.size, + elementTypeLayout.getStride() * (elementCount - 1) + elementTypeLayout.size, elementTypeLayout.alignment); return SLANG_OK; } @@ -85,308 +83,8 @@ IRIntegerValue getIntegerValueFromInst(IRInst* inst) return as<IRIntLit>(inst)->value.intVal; } -static Result _calcNaturalSizeAndAlignment( - TargetRequest* target, - IRType* type, - IRSizeAndAlignment* outSizeAndAlignment) -{ - switch( type->getOp() ) - { - -#define CASE(TYPE, SIZE, ALIGNMENT) \ - case kIROp_##TYPE##Type: \ - *outSizeAndAlignment = IRSizeAndAlignment(SIZE, ALIGNMENT); \ - return SLANG_OK \ - /* end */ - - // Most base types are "naturally aligned" (meaning alignment and size are the same) -#define BASE(TYPE, SIZE) CASE(TYPE, SIZE, SIZE) - - BASE(Int8, 1); - BASE(UInt8, 1); - - BASE(Int16, 2); - BASE(UInt16, 2); - BASE(Half, 2); - - BASE(Int, 4); - BASE(UInt, 4); - BASE(Float, 4); - - BASE(Int64, 8); - BASE(UInt64, 8); - BASE(Double, 8); - - // 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 - // type, so that it does not influence layout at all. - // - CASE(Void, 0, 1); - -#undef CASE - -#undef CASE - - case kIROp_StructType: - { - auto structType = cast<IRStructType>(type); - IRSizeAndAlignment structLayout; - for( auto field : structType->getFields() ) - { - IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(target, field->getFieldType(), &fieldTypeLayout)); - - structLayout.size = align(structLayout.size, fieldTypeLayout.alignment); - structLayout.alignment = std::max(structLayout.alignment, fieldTypeLayout.alignment); - - IRIntegerValue fieldOffset = structLayout.size; - if( auto module = type->getModule() ) - { - // If we are in a situation where attaching new - // decorations is possible, then we want to - // cache the field offset on the IR field - // instruction. - // - IRBuilder builder(module); - - auto intType = builder.getIntType(); - builder.addDecoration( - field, - kIROp_NaturalOffsetDecoration, - builder.getIntValue(intType, fieldOffset)); - } - - structLayout.size += fieldTypeLayout.size; - } - *outSizeAndAlignment = structLayout; - return SLANG_OK; - } - break; - - case kIROp_ArrayType: - { - auto arrayType = cast<IRArrayType>(type); - - return _calcNaturalArraySizeAndAlignment( - target, - arrayType->getElementType(), - arrayType->getElementCount(), - outSizeAndAlignment); - } - break; - - case kIROp_VectorType: - { - auto vecType = cast<IRVectorType>(type); - - return _calcNaturalArraySizeAndAlignment( - target, - vecType->getElementType(), - vecType->getElementCount(), - outSizeAndAlignment); - } - break; - case kIROp_AnyValueType: - { - auto anyValType = cast<IRAnyValueType>(type); - outSizeAndAlignment->size = getIntVal(anyValType->getSize()); - outSizeAndAlignment->alignment = 4; - return SLANG_OK; - } - break; - case kIROp_TupleType: - { - auto tupleType = cast<IRTupleType>(type); - IRSizeAndAlignment resultLayout; - for (UInt i = 0; i < tupleType->getOperandCount(); i++) - { - auto elementType = tupleType->getOperand(i); - IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(target, (IRType*)elementType, &fieldTypeLayout)); - resultLayout.size = align(resultLayout.size, fieldTypeLayout.alignment); - resultLayout.alignment = std::max(resultLayout.alignment, fieldTypeLayout.alignment); - } - *outSizeAndAlignment = resultLayout; - return SLANG_OK; - } - break; - case kIROp_WitnessTableType: - case kIROp_WitnessTableIDType: - case kIROp_RTTIHandleType: - { - outSizeAndAlignment->size = kRTTIHandleSize; - outSizeAndAlignment->alignment = 4; - return SLANG_OK; - } - break; - case kIROp_InterfaceType: - { - auto interfaceType = cast<IRInterfaceType>(type); - auto size = SharedGenericsLoweringContext::getInterfaceAnyValueSize(interfaceType, interfaceType->sourceLoc); - size += kRTTIHeaderSize; - size = align(size, 4); - IRSizeAndAlignment resultLayout; - resultLayout.size = size; - resultLayout.alignment = 4; - *outSizeAndAlignment = resultLayout; - return SLANG_OK; - } - break; - case kIROp_MatrixType: - { - auto matType = cast<IRMatrixType>(type); - auto rowCount = getIntegerValueFromInst(matType->getRowCount()); - auto colCount = getIntegerValueFromInst(matType->getColumnCount()); - IRBuilder builder(type->getModule()); - - return _calcNaturalArraySizeAndAlignment( - target, matType->getElementType(), - builder.getIntValue(builder.getUIntType(), rowCount * colCount), - outSizeAndAlignment); - } - break; - case kIROp_OutType: - case kIROp_InOutType: - case kIROp_RefType: - case kIROp_RawPointerType: - case kIROp_PtrType: - case kIROp_NativePtrType: - case kIROp_ComPtrType: - case kIROp_NativeStringType: - { - *outSizeAndAlignment = IRSizeAndAlignment(sizeof(void*), sizeof(void*)); - return SLANG_OK; - } - break; - default: - break; - } - - if( areResourceTypesBindlessOnTarget(target) ) - { - // TODO: need this to be based on target, instead of hard-coded - int pointerSize = sizeof(void*); - - if(as<IRTextureType>(type) ) - { - *outSizeAndAlignment = IRSizeAndAlignment(pointerSize, pointerSize); - return SLANG_OK; - } - else if(as<IRSamplerStateTypeBase>(type) ) - { - *outSizeAndAlignment = IRSizeAndAlignment(pointerSize, pointerSize); - return SLANG_OK; - } - // TODO: the remaining cases for "bindless" resources on CPU/CUDA targets - } - - return SLANG_FAIL; -} - -Result getNaturalSizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) -{ - if( auto decor = type->findDecoration<IRNaturalSizeAndAlignmentDecoration>() ) - { - *outSizeAndAlignment = IRSizeAndAlignment(decor->getSize(), (int)decor->getAlignment()); - return SLANG_OK; - } - - IRSizeAndAlignment sizeAndAlignment; - SLANG_RETURN_ON_FAIL(_calcNaturalSizeAndAlignment(target, type, &sizeAndAlignment)); - - if( auto module = type->getModule() ) - { - IRBuilder builder(module); - - auto intType = builder.getIntType(); - builder.addDecoration( - type, - kIROp_NaturalSizeAndAlignmentDecoration, - builder.getIntValue(intType, sizeAndAlignment.size), - builder.getIntValue(intType, sizeAndAlignment.alignment)); - } - - *outSizeAndAlignment = sizeAndAlignment; - return SLANG_OK; -} - - -Result getNaturalOffset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset) -{ - if( auto decor = field->findDecoration<IRNaturalOffsetDecoration>() ) - { - *outOffset = decor->getOffset(); - return SLANG_OK; - } - - // Offsets are computed as part of layout out types, - // so we expect that layout of the "parent" type - // of the field should add an offset to it if - // possible. - - auto structType = as<IRStructType>(field->getParent()); - if(!structType) - return SLANG_FAIL; - - IRSizeAndAlignment structTypeLayout; - SLANG_RETURN_ON_FAIL(getNaturalSizeAndAlignment(target, structType, &structTypeLayout)); - - if( auto decor = field->findDecoration<IRNaturalOffsetDecoration>() ) - { - *outOffset = decor->getOffset(); - return SLANG_OK; - } - - // If attempting to lay out the parent type didn't - // cause the field to get an offset, then we are - // in an unexpected case with no easy answer. - // - return SLANG_FAIL; -} - - -////////////////////////// -// Std430 Layout -////////////////////////// - -static Result _calcStd430ArraySizeAndAlignment( - TargetRequest* target, - IRType* elementType, - IRInst* elementCountInst, - IRSizeAndAlignment* outSizeAndAlignment) -{ - auto elementCountLit = as<IRIntLit>(elementCountInst); - if (!elementCountLit) - return SLANG_FAIL; - auto elementCount = elementCountLit->getValue(); - - if (elementCount == 0) - { - *outSizeAndAlignment = IRSizeAndAlignment(0, 1); - return SLANG_OK; - } - - IRSizeAndAlignment elementTypeLayout; - SLANG_RETURN_ON_FAIL(getStd430SizeAndAlignment(target, elementType, &elementTypeLayout)); - - auto elementStride = elementTypeLayout.getStride(); - - *outSizeAndAlignment = IRSizeAndAlignment( - elementStride * (elementCount - 1) + elementTypeLayout.size, - elementTypeLayout.alignment); - return SLANG_OK; -} - -static Result _calcStd430SizeAndAlignment( - TargetRequest* target, +static Result _calcSizeAndAlignment( + IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { @@ -394,12 +92,12 @@ static Result _calcStd430SizeAndAlignment( { #define CASE(TYPE, SIZE, ALIGNMENT) \ - case kIROp_##TYPE##Type: \ - *outSizeAndAlignment = IRSizeAndAlignment(SIZE, ALIGNMENT); \ - return SLANG_OK \ - /* end */ +case kIROp_##TYPE##Type: \ + *outSizeAndAlignment = IRSizeAndAlignment(SIZE, ALIGNMENT); \ + return SLANG_OK \ + /* end */ - // Most base types are "std430 aligned" (meaning alignment and size are the same) + // Most base types are "naturally aligned" (meaning alignment and size are the same) #define BASE(TYPE, SIZE) CASE(TYPE, SIZE, SIZE) BASE(Int8, 1); @@ -415,6 +113,8 @@ static Result _calcStd430SizeAndAlignment( BASE(Int64, 8); BASE(UInt64, 8); + BASE(IntPtr, 8); + BASE(UIntPtr, 8); BASE(Double, 8); // We are currently handling `bool` following the HLSL @@ -442,8 +142,7 @@ static Result _calcStd430SizeAndAlignment( for (auto field : structType->getFields()) { IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getStd430SizeAndAlignment(target, field->getFieldType(), &fieldTypeLayout)); - + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(rules, field->getFieldType(), &fieldTypeLayout)); structLayout.size = align(structLayout.size, fieldTypeLayout.alignment); structLayout.alignment = std::max(structLayout.alignment, fieldTypeLayout.alignment); @@ -460,13 +159,14 @@ static Result _calcStd430SizeAndAlignment( auto intType = builder.getIntType(); builder.addDecoration( field, - kIROp_Std430OffsetDecoration, + kIROp_OffsetDecoration, + builder.getIntValue(intType, (IRIntegerValue)rules->ruleName), builder.getIntValue(intType, fieldOffset)); } structLayout.size += fieldTypeLayout.size; } - *outSizeAndAlignment = structLayout; + *outSizeAndAlignment = rules->alignCompositeElement(structLayout); return SLANG_OK; } break; @@ -475,8 +175,8 @@ static Result _calcStd430SizeAndAlignment( { auto arrayType = cast<IRArrayType>(type); - return _calcStd430ArraySizeAndAlignment( - target, + return _calcArraySizeAndAlignment( + rules , arrayType->getElementType(), arrayType->getElementCount(), outSizeAndAlignment); @@ -486,15 +186,9 @@ static Result _calcStd430SizeAndAlignment( case kIROp_VectorType: { auto vecType = cast<IRVectorType>(type); - auto elementCount = getIntegerValueFromInst(vecType->getElementCount()); - auto alignmentMultiplier = elementCount; - if (elementCount == 3) - alignmentMultiplier = 4; - IRSizeAndAlignment sizeAndAlignment; - SLANG_RETURN_ON_FAIL(getStd430SizeAndAlignment(target, vecType->getElementType(), &sizeAndAlignment)); - sizeAndAlignment.size *= (int)elementCount; - sizeAndAlignment.alignment *= (int)alignmentMultiplier; - *outSizeAndAlignment = sizeAndAlignment; + IRSizeAndAlignment elementTypeLayout; + getSizeAndAlignment(rules, vecType->getElementType(), &elementTypeLayout); + *outSizeAndAlignment = rules->getVectorSizeAndAlignment(elementTypeLayout, getIntegerValueFromInst(vecType->getElementCount())); return SLANG_OK; } break; @@ -503,6 +197,7 @@ static Result _calcStd430SizeAndAlignment( auto anyValType = cast<IRAnyValueType>(type); outSizeAndAlignment->size = getIntVal(anyValType->getSize()); outSizeAndAlignment->alignment = 4; + *outSizeAndAlignment = rules->alignCompositeElement(*outSizeAndAlignment); return SLANG_OK; } break; @@ -514,11 +209,11 @@ static Result _calcStd430SizeAndAlignment( { auto elementType = tupleType->getOperand(i); IRSizeAndAlignment fieldTypeLayout; - SLANG_RETURN_ON_FAIL(getStd430SizeAndAlignment(target, (IRType*)elementType, &fieldTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(rules, (IRType*)elementType, &fieldTypeLayout)); resultLayout.size = align(resultLayout.size, fieldTypeLayout.alignment); resultLayout.alignment = std::max(resultLayout.alignment, fieldTypeLayout.alignment); } - *outSizeAndAlignment = resultLayout; + *outSizeAndAlignment = rules->alignCompositeElement(resultLayout); return SLANG_OK; } break; @@ -540,7 +235,7 @@ static Result _calcStd430SizeAndAlignment( IRSizeAndAlignment resultLayout; resultLayout.size = size; resultLayout.alignment = 4; - *outSizeAndAlignment = resultLayout; + *outSizeAndAlignment = rules->alignCompositeElement(resultLayout); return SLANG_OK; } break; @@ -548,12 +243,24 @@ static Result _calcStd430SizeAndAlignment( { auto matType = cast<IRMatrixType>(type); IRBuilder builder(type->getModule()); - builder.setInsertBefore(matType); - auto rowType = builder.getVectorType(matType->getElementType(), matType->getColumnCount()); - return _calcStd430ArraySizeAndAlignment( - target, rowType, - matType->getRowCount(), - outSizeAndAlignment); + if (getIntegerValueFromInst(matType->getLayout()) == SLANG_MATRIX_LAYOUT_COLUMN_MAJOR) + { + auto colVector = builder.getVectorType(matType->getElementType(), matType->getRowCount()); + return _calcArraySizeAndAlignment( + rules, + colVector, + matType->getColumnCount(), + outSizeAndAlignment); + } + else + { + auto rowVector = builder.getVectorType(matType->getElementType(), matType->getColumnCount()); + return _calcArraySizeAndAlignment( + rules, + rowVector, + matType->getRowCount(), + outSizeAndAlignment); + } } break; case kIROp_OutType: @@ -564,46 +271,46 @@ static Result _calcStd430SizeAndAlignment( case kIROp_NativePtrType: case kIROp_ComPtrType: case kIROp_NativeStringType: + case kIROp_HLSLConstBufferPointerType: { - *outSizeAndAlignment = IRSizeAndAlignment(sizeof(void*), sizeof(void*)); + *outSizeAndAlignment = IRSizeAndAlignment(8, 8); return SLANG_OK; } break; default: break; } - - if (areResourceTypesBindlessOnTarget(target)) + if (as<IRResourceTypeBase>(type) || as<IRSamplerStateTypeBase>(type)) { - // TODO: need this to be based on target, instead of hard-coded - int pointerSize = sizeof(void*); + *outSizeAndAlignment = IRSizeAndAlignment(8, 8); + return SLANG_OK; + } + return SLANG_FAIL; +} - if (as<IRTextureType>(type)) - { - *outSizeAndAlignment = IRSizeAndAlignment(pointerSize, pointerSize); - return SLANG_OK; - } - else if (as<IRSamplerStateTypeBase>(type)) +IRSizeAndAlignmentDecoration* findSizeAndAlignmentDecorationForLayout(IRType* type, IRTypeLayoutRuleName layoutName) +{ + for (auto decorInst : type->getDecorations()) + { + if (auto decor = as<IRSizeAndAlignmentDecoration>(decorInst)) { - *outSizeAndAlignment = IRSizeAndAlignment(pointerSize, pointerSize); - return SLANG_OK; + if (decor->getLayoutName() == layoutName) + return decor; } - // TODO: the remaining cases for "bindless" resources on CPU/CUDA targets } - - return SLANG_FAIL; + return nullptr; } -Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +Result getSizeAndAlignment(IRTypeLayoutRules* rules, IRType* type, IRSizeAndAlignment* outSizeAndAlignment) { - if (auto decor = type->findDecoration<IRStd430SizeAndAlignmentDecoration>()) + if (auto decor = findSizeAndAlignmentDecorationForLayout(type, rules->ruleName)) { *outSizeAndAlignment = IRSizeAndAlignment(decor->getSize(), (int)decor->getAlignment()); return SLANG_OK; } IRSizeAndAlignment sizeAndAlignment; - SLANG_RETURN_ON_FAIL(_calcStd430SizeAndAlignment(target, type, &sizeAndAlignment)); + SLANG_RETURN_ON_FAIL(_calcSizeAndAlignment(rules, type, &sizeAndAlignment)); if (auto module = type->getModule()) { @@ -612,7 +319,8 @@ Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndA auto intType = builder.getIntType(); builder.addDecoration( type, - kIROp_Std430SizeAndAlignmentDecoration, + kIROp_SizeAndAlignmentDecoration, + builder.getIntValue(intType, (IRIntegerValue)rules->ruleName), builder.getIntValue(intType, sizeAndAlignment.size), builder.getIntValue(intType, sizeAndAlignment.alignment)); } @@ -620,11 +328,22 @@ Result getStd430SizeAndAlignment(TargetRequest* target, IRType* type, IRSizeAndA *outSizeAndAlignment = sizeAndAlignment; return SLANG_OK; } +IROffsetDecoration* findOffsetDecorationForLayout(IRStructField* field, IRTypeLayoutRuleName layoutName) +{ + for (auto decorInst : field->getDecorations()) + { + if (auto decor = as<IROffsetDecoration>(decorInst)) + { + if (decor->getLayoutName() == layoutName) + return decor; + } + } + return nullptr; +} - -Result getStd430Offset(TargetRequest* target, IRStructField* field, IRIntegerValue* outOffset) +Result getOffset(IRTypeLayoutRules* rules, IRStructField* field, IRIntegerValue* outOffset) { - if (auto decor = field->findDecoration<IRStd430OffsetDecoration>()) + if (auto decor = findOffsetDecorationForLayout(field, rules->ruleName)) { *outOffset = decor->getOffset(); return SLANG_OK; @@ -640,9 +359,9 @@ Result getStd430Offset(TargetRequest* target, IRStructField* field, IRIntegerVal return SLANG_FAIL; IRSizeAndAlignment structTypeLayout; - SLANG_RETURN_ON_FAIL(getStd430SizeAndAlignment(target, structType, &structTypeLayout)); + SLANG_RETURN_ON_FAIL(getSizeAndAlignment(rules, structType, &structTypeLayout)); - if (auto decor = field->findDecoration<IRStd430OffsetDecoration>()) + if (auto decor = findOffsetDecorationForLayout(field, rules->ruleName)) { *outOffset = decor->getOffset(); return SLANG_OK; @@ -655,5 +374,113 @@ Result getStd430Offset(TargetRequest* target, IRStructField* field, IRIntegerVal return SLANG_FAIL; } +struct NaturalLayoutRules : IRTypeLayoutRules +{ + NaturalLayoutRules() + { + ruleName = IRTypeLayoutRuleName::Natural; + } + + virtual IRSizeAndAlignment alignCompositeElement(IRSizeAndAlignment elementSize) + { + return elementSize; + } + virtual IRSizeAndAlignment getVectorSizeAndAlignment(IRSizeAndAlignment element, IRIntegerValue count) + { + return IRSizeAndAlignment(element.size * count, element.alignment); + } +}; + +struct Std430LayoutRules : IRTypeLayoutRules +{ + Std430LayoutRules() + { + ruleName = IRTypeLayoutRuleName::Std430; + } + + virtual IRSizeAndAlignment alignCompositeElement(IRSizeAndAlignment elementSize) + { + return elementSize; + } + virtual IRSizeAndAlignment getVectorSizeAndAlignment(IRSizeAndAlignment element, IRIntegerValue count) + { + if (count == 3) + count = 4; + return IRSizeAndAlignment((int)(element.size * count), (int)(element.size * count)); + } +}; + +struct Std140LayoutRules : IRTypeLayoutRules +{ + Std140LayoutRules() + { + ruleName = IRTypeLayoutRuleName::Std140; + } + + virtual IRSizeAndAlignment alignCompositeElement(IRSizeAndAlignment elementSize) + { + elementSize.alignment = (int)align(elementSize.alignment, 16); + elementSize.size = align(elementSize.size, elementSize.alignment); + return elementSize; + } + virtual IRSizeAndAlignment getVectorSizeAndAlignment(IRSizeAndAlignment element, IRIntegerValue count) + { + if (count == 3) + count = 4; + return IRSizeAndAlignment((int)(element.size * count), (int)(element.size * count)); + } +}; + +Result getNaturalSizeAndAlignment(IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +{ + return getSizeAndAlignment(IRTypeLayoutRules::getNatural(), type, outSizeAndAlignment); + +} + +Result getNaturalOffset(IRStructField* field, IRIntegerValue* outOffset) +{ + return getOffset(IRTypeLayoutRules::getNatural(), field, outOffset); +} + + +////////////////////////// +// Std430 Layout +////////////////////////// + +Result getStd430SizeAndAlignment(IRType* type, IRSizeAndAlignment* outSizeAndAlignment) +{ + return getSizeAndAlignment(IRTypeLayoutRules::getStd430(), type, outSizeAndAlignment); +} + +Result getStd430Offset(IRStructField* field, IRIntegerValue* outOffset) +{ + return getOffset(IRTypeLayoutRules::getStd430(), field, outOffset); +} + +IRTypeLayoutRules* IRTypeLayoutRules::getStd430() +{ + static Std430LayoutRules rules; + return &rules; +} +IRTypeLayoutRules* IRTypeLayoutRules::getStd140() +{ + static Std140LayoutRules rules; + return &rules; +} +IRTypeLayoutRules* IRTypeLayoutRules::getNatural() +{ + static NaturalLayoutRules rules; + return &rules; +} +IRTypeLayoutRules* IRTypeLayoutRules::get(IRTypeLayoutRuleName name) +{ + switch (name) + { + case IRTypeLayoutRuleName::Std430: return getStd430(); + case IRTypeLayoutRuleName::Std140: return getStd140(); + case IRTypeLayoutRuleName::Natural: return getNatural(); + default: return nullptr; + } +} } |
