Edit

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

Branch :

  • Show log

    Commit

  • Author : Qin Jiajia
    Date : 2018-10-19 17:01:17
    Hash : 672267fc
    Message : ES31: Fix that asuint can't accept bool value This change fixes below errors: error X3013: 'asuint': no matching 1 parameter intrinsic function error X3013: Possible intrinsic functions are: error X3013: asuint(double, out uint x, out uint y) error X3013: asuint(float|half|int|uint) When we store a boolean value, we should cast it to uint firstly. Then do the store. Bug: angleproject:1951 Change-Id: I8931e540d701ef72bb82846496c698acef1ba1fb Reviewed-on: https://chromium-review.googlesource.com/c/1295831 Commit-Queue: Jiajia Qin <jiajia.qin@intel.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
  • //
    // Copyright 2018 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.
    //
    // ShaderStorageBlockFunctionHLSL: Wrapper functions for RWByteAddressBuffer Load/Store functions.
    //
    
    #include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
    
    #include "compiler/translator/UtilsHLSL.h"
    #include "compiler/translator/blocklayout.h"
    #include "compiler/translator/blocklayoutHLSL.h"
    #include "compiler/translator/util.h"
    
    namespace sh
    {
    
    namespace
    {
    
    unsigned int GetMatrixStride(const TType &type)
    {
        sh::Std140BlockEncoder std140Encoder;
        sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
        sh::BlockLayoutEncoder *encoder = nullptr;
    
        if (type.getLayoutQualifier().blockStorage == EbsStd140)
        {
            encoder = &std140Encoder;
        }
        else
        {
            // TODO(jiajia.qin@intel.com): add std430 support. http://anglebug.com/1951
            encoder = &hlslEncoder;
        }
        const bool isRowMajorLayout = (type.getLayoutQualifier().matrixPacking == EmpRowMajor);
        std::vector<unsigned int> arraySizes;
        auto *typeArraySizes = type.getArraySizes();
        if (typeArraySizes != nullptr)
        {
            arraySizes.assign(typeArraySizes->begin(), typeArraySizes->end());
        }
        const BlockMemberInfo &memberInfo =
            encoder->encodeType(GLVariableType(type), arraySizes, isRowMajorLayout);
        return memberInfo.matrixStride;
    }
    
    }  // anonymous namespace
    
    // static
    void ShaderStorageBlockFunctionHLSL::OutputSSBOLoadFunctionBody(
        TInfoSinkBase &out,
        const ShaderStorageBlockFunction &ssboFunction)
    {
        const char *convertString;
        switch (ssboFunction.type.getBasicType())
        {
            case EbtFloat:
                convertString = "asfloat(";
                break;
            case EbtInt:
                convertString = "asint(";
                break;
            case EbtUInt:
                convertString = "asuint(";
                break;
            case EbtBool:
                convertString = "asint(";
                break;
            default:
                UNREACHABLE();
                return;
        }
    
        out << "    " << ssboFunction.typeString << " result";
        if (ssboFunction.type.isScalar())
        {
            out << " = " << convertString << "buffer.Load(loc));\n";
        }
        else if (ssboFunction.type.isVector())
        {
            out << " = " << convertString << "buffer.Load" << ssboFunction.type.getNominalSize()
                << "(loc));\n";
        }
        else if (ssboFunction.type.isMatrix())
        {
            unsigned int matrixStride = GetMatrixStride(ssboFunction.type);
            out << " = {";
            for (int rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
            {
                out << "asfloat(buffer.Load" << ssboFunction.type.getCols() << "(loc +"
                    << rowIndex * matrixStride << ")), ";
            }
    
            out << "};\n";
        }
        else
        {
            // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
            out << ";\n";
        }
    
        out << "    return result;\n";
        return;
    }
    
    // static
    void ShaderStorageBlockFunctionHLSL::OutputSSBOStoreFunctionBody(
        TInfoSinkBase &out,
        const ShaderStorageBlockFunction &ssboFunction)
    {
        if (ssboFunction.type.isScalar())
        {
            if (ssboFunction.type.getBasicType() == EbtBool)
            {
                out << "    uint _tmp = uint(value);\n"
                    << "    buffer.Store(loc, _tmp);\n";
            }
            else
            {
                out << "    buffer.Store(loc, asuint(value));\n";
            }
        }
        else if (ssboFunction.type.isVector())
        {
            if (ssboFunction.type.getBasicType() == EbtBool)
            {
                out << "    uint" << ssboFunction.type.getNominalSize() << " _tmp = uint"
                    << ssboFunction.type.getNominalSize() << "(value);\n";
                out << "    buffer.Store" << ssboFunction.type.getNominalSize() << "(loc, _tmp);\n";
            }
            else
            {
                out << "    buffer.Store" << ssboFunction.type.getNominalSize()
                    << "(loc, asuint(value));\n";
            }
        }
        else if (ssboFunction.type.isMatrix())
        {
            unsigned int matrixStride = GetMatrixStride(ssboFunction.type);
            for (int rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
            {
                out << "    buffer.Store" << ssboFunction.type.getCols() << "(loc +"
                    << rowIndex * matrixStride << ", asuint(value[" << rowIndex << "]));\n";
            }
        }
        else
        {
            // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
        }
    }
    
    bool ShaderStorageBlockFunctionHLSL::ShaderStorageBlockFunction::operator<(
        const ShaderStorageBlockFunction &rhs) const
    {
        return std::tie(functionName, typeString, method) <
               std::tie(rhs.functionName, rhs.typeString, rhs.method);
    }
    
    TString ShaderStorageBlockFunctionHLSL::registerShaderStorageBlockFunction(const TType &type,
                                                                               SSBOMethod method)
    {
        ShaderStorageBlockFunction ssboFunction;
        ssboFunction.typeString = TypeString(type);
        ssboFunction.method     = method;
        ssboFunction.type       = type;
    
        switch (method)
        {
            case SSBOMethod::LOAD:
                ssboFunction.functionName = ssboFunction.typeString + "_Load";
                break;
            case SSBOMethod::STORE:
                ssboFunction.functionName = ssboFunction.typeString + "_Store";
                break;
            default:
                UNREACHABLE();
        }
    
        mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
        return ssboFunction.functionName;
    }
    
    void ShaderStorageBlockFunctionHLSL::shaderStorageBlockFunctionHeader(TInfoSinkBase &out)
    {
        for (const ShaderStorageBlockFunction &ssboFunction : mRegisteredShaderStorageBlockFunctions)
        {
            if (ssboFunction.method == SSBOMethod::LOAD)
            {
                // Function header
                out << ssboFunction.typeString << " " << ssboFunction.functionName
                    << "(RWByteAddressBuffer buffer, uint loc)\n";
                out << "{\n";
                OutputSSBOLoadFunctionBody(out, ssboFunction);
            }
            else
            {
                // Function header
                out << "void " << ssboFunction.functionName << "(RWByteAddressBuffer buffer, uint loc, "
                    << ssboFunction.typeString << " value)\n";
                out << "{\n";
                OutputSSBOStoreFunctionBody(out, ssboFunction);
            }
    
            out << "}\n"
                   "\n";
        }
    }
    
    }  // namespace sh