Repository: shader-slang/slang
File: source/slang/slang-ir-lower-buffer-element-type.cpp (C++)

Code before:

IRTypeLayoutRuleName getTypeLayoutRuleNameForBuffer(TargetProgram* target, IRType* bufferType)
{
    if (bufferType->getOp() == kIROp_ParameterBlockType && isMetalTarget(target->getTargetReq()))
    {
        return IRTypeLayoutRuleName::MetalParameterBlock;
    }
    auto targetReq = target->getTargetReq();
    if (targetReq->getTarget() != CodeGenTarget::WGSL)
    {
        if (!isKhronosTarget(target->getTargetReq()) && !isCPUTargetViaLLVM(targetReq))
            return IRTypeLayoutRuleName::Natural;

        // If we are just emitting GLSL, we can just use the general layout rule.
        if (!target->shouldEmitSPIRVDirectly() && !isCPUTargetViaLLVM(targetReq))
            return IRTypeLayoutRuleName::Natural;

        // If the user specified a C-compatible buffer layout, then do that.
        if (target->getOptionSet().shouldUseCLayout())
            return IRTypeLayoutRuleName::C;

        // If the user specified a scalar buffer layout, then just use that.
        if (target->getOptionSet().shouldUseScalarLayout())
            return IRTypeLayoutRuleName::Natural;
    }

    if (target->getOptionSet().shouldUseDXLayout())
    {
        if (as<IRUniformParameterGroupType>(bufferType))
        {
            return IRTypeLayoutRuleName::D3DConstantBuffer;
        }
        else
            return IRTypeLayoutRuleName::Natural;
    }

    // The default behavior is to use std140 for constant buffers and std430 for other buffers.
    switch (bufferType->getOp())
    {
    case kIROp_HLSLStructuredBufferType:
    case kIROp_HLSLRWStructuredBufferType:
    case kIROp_HLSLAppendStructuredBufferType:
    case kIROp_HLSLConsumeStructuredBufferType:
    case kIROp_HLSLRasterizerOrderedStructuredBufferType:
        {
            auto structBufferType = as<IRHLSLStructuredBufferTypeBase>(bufferType);
            auto layoutTypeOp = structBufferType->getDataLayout()
                                    ? structBufferType->getDataLayout()->getOp()
                                    : kIROp_DefaultBufferLayoutType;
            return getTypeLayoutRulesFromOp(layoutTypeOp, IRTypeLayoutRuleName::Std430);
        }

Review comment (suggestion):
Nitpick: Perhaps these should conditions should be `auto dataLayout = paramGroupType->getDataLayout()`, etc., so that we do not make the same `getDataLayout()` twice.

Code after:
}

IRTypeLayoutRuleName getTypeLayoutRuleNameForBuffer(TargetProgram* target, IRType* bufferType)
{
    if (bufferType->getOp() == kIROp_ParameterBlockType && isMetalTarget(target->getTargetReq()))
    {
        return IRTypeLayoutRuleName::MetalParameterBlock;
    }
    auto targetReq = target->getTargetReq();
    if (targetReq->getTarget() != CodeGenTarget::WGSL)
    {
        if (!isKhronosTarget(target->getTargetReq()) && !isCPUTargetViaLLVM(targetReq))
            return IRTypeLayoutRuleName::Natural;

        // If we are just emitting GLSL, we can just use the general layout rule.
        if (!target->shouldEmitSPIRVDirectly() && !isCPUTargetViaLLVM(targetReq))
            return IRTypeLayoutRuleName::Natural;

        // An explicit (non-default) layout annotation on the buffer takes precedence
        // over global compiler options such as forceScalarLayout.
        {
            IROp layoutTypeOp = kIROp_DefaultBufferLayoutType;
            if (auto paramGroupType = as<IRUniformParameterGroupType>(bufferType))
            {
                if (paramGroupType->getDataLayout())
                    layoutTypeOp = paramGroupType->getDataLayout()->getOp();
            }
            else if (auto structBufferType = as<IRHLSLStructuredBufferTypeBase>(bufferType))
            {
                if (structBufferType->getDataLayout())
                    layoutTypeOp = structBufferType->getDataLayout()->getOp();
            }
            else if (auto storageBufferType = as<IRGLSLShaderStorageBufferType>(bufferType))
            {
                if (storageBufferType->getDataLayout())
                    layoutTypeOp = storageBufferType->getDataLayout()->getOp();
            }
            if (layoutTypeOp != kIROp_DefaultBufferLayoutType &&
                layoutTypeOp != kIROp_DefaultPushConstantBufferLayoutType)
            {
                return getTypeLayoutRulesFromOp(layoutTypeOp, IRTypeLayoutRuleName::Natural);
            }
        }

        // If the user specified a C-compatible buffer layout, then do that.
        if (target->getOptionSet().shouldUseCLayout())
            return IRTypeLayoutRuleName::C;

        // If the user specified a scalar buffer layout, then just use that.
        if (target->getOptionSet().shouldUseScalarLayout())
            return IRTypeLayoutRuleName::Natural;