Edit

kc3-lang/angle/src/compiler/translator/blocklayoutHLSL.cpp

Branch :

  • Show log

    Commit

  • Author : Tim Van Patten
    Date : 2019-09-04 15:39:58
    Hash : 90a58622
    Message : Refactor ShaderVariable to Remove Specializations The following structs are being refactored and moved into the parent struct ShaderVariable: VariableWithLocation Uniform Attribute OutputVariable InterfaceBlockField Varying Bug: angleproject:3899 Test: CQ Change-Id: I389eb3ab4ed44a360e09fca75ecc78d64a277f83 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1785877 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Tim Van Patten <timvp@google.com>

  • src/compiler/translator/blocklayoutHLSL.cpp
  • //
    // Copyright 2013 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // blocklayout.cpp:
    //   Implementation for block layout classes and methods.
    //
    
    #include "compiler/translator/blocklayoutHLSL.h"
    
    #include "common/mathutil.h"
    #include "common/utilities.h"
    
    namespace sh
    {
    
    HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices)
        : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
    {}
    
    void HLSLBlockEncoder::enterAggregateType(const ShaderVariable &structVar)
    {
        align(kComponentsPerRegister);
    }
    
    void HLSLBlockEncoder::exitAggregateType(const ShaderVariable &structVar) {}
    
    void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
                                              const std::vector<unsigned int> &arraySizes,
                                              bool isRowMajorMatrix,
                                              int *arrayStrideOut,
                                              int *matrixStrideOut)
    {
        GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
    
        // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
        ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
    
        int matrixStride = 0;
        int arrayStride  = 0;
    
        // if variables are not to be packed, or we're about to
        // pack a matrix or array, skip to the start of the next
        // register
        if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
        {
            align(kComponentsPerRegister);
        }
    
        if (gl::IsMatrixType(type))
        {
            matrixStride = kComponentsPerRegister;
    
            if (!arraySizes.empty())
            {
                const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
                arrayStride            = kComponentsPerRegister * numRegisters;
            }
        }
        else if (!arraySizes.empty())
        {
            arrayStride = kComponentsPerRegister;
        }
        else if (isPacked())
        {
            int numComponents = gl::VariableComponentCount(type);
            if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister)
            {
                align(kComponentsPerRegister);
            }
        }
    
        *matrixStrideOut = matrixStride;
        *arrayStrideOut  = arrayStride;
    }
    
    void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
                                         const std::vector<unsigned int> &arraySizes,
                                         bool isRowMajorMatrix,
                                         int arrayStride,
                                         int matrixStride)
    {
        GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
    
        if (!arraySizes.empty())
        {
            unsigned int arraySize = gl::ArraySizeProduct(arraySizes);
            if (arraySize > 0)
            {
                mCurrentOffset += arrayStride * (arraySize - 1);
            }
        }
    
        if (gl::IsMatrixType(type))
        {
            ASSERT(matrixStride == kComponentsPerRegister);
            const int numRegisters  = gl::MatrixRegisterCount(type, isRowMajorMatrix);
            const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
            mCurrentOffset += kComponentsPerRegister * (numRegisters - 1);
            mCurrentOffset += numComponents;
        }
        else if (isPacked())
        {
            mCurrentOffset += gl::VariableComponentCount(type);
        }
        else
        {
            mCurrentOffset += kComponentsPerRegister;
        }
    }
    
    void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
    {
        mCurrentOffset += (numRegisters * kComponentsPerRegister);
    }
    
    HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(
        ShShaderOutput outputType)
    {
        switch (outputType)
        {
            case SH_HLSL_3_0_OUTPUT:
                return ENCODE_LOOSE;
            case SH_HLSL_4_1_OUTPUT:
            case SH_HLSL_4_0_FL9_3_OUTPUT:
                return ENCODE_PACKED;
            default:
                UNREACHABLE();
                return ENCODE_PACKED;
        }
    }
    
    template <class ShaderVarType>
    void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
    {
        if (variable.isStruct())
        {
            for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
            {
                encoder->enterAggregateType(variable);
    
                for (const ShaderVariable &field : variable.fields)
                {
                    HLSLVariableRegisterCount(field, encoder);
                }
    
                encoder->exitAggregateType(variable);
            }
        }
        else
        {
            // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
            encoder->encodeType(variable.type, variable.arraySizes, false);
        }
    }
    
    unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType)
    {
        HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
        HLSLVariableRegisterCount(variable, &encoder);
    
        const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister);
        return static_cast<unsigned int>(
            rx::roundUp<size_t>(encoder.getCurrentOffset(), registerBytes) / registerBytes);
    }
    }  // namespace sh