Edit

kc3-lang/angle/src/tests/perf_tests/BufferSubData.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2020-08-12 14:27:42
    Hash : cc958e0e
    Message : Remove D3D9 configs from perf tests. We are not maintaining D3D9 for performance and reducing the number of perf tests will speed up the bots. Bug: angleproject:4943 Change-Id: Ib4ddad2cbfefcf6fccf3307df3bac7565ef246f4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2352478 Reviewed-by: Yuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/tests/perf_tests/BufferSubData.cpp
  • //
    // Copyright 2014 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.
    //
    // BufferSubDataBenchmark:
    //   Performance test for ANGLE buffer updates.
    //
    
    #include <sstream>
    
    #include "ANGLEPerfTest.h"
    #include "test_utils/draw_call_perf_utils.h"
    
    using namespace angle;
    
    namespace
    {
    constexpr unsigned int kIterationsPerStep = 4;
    
    struct BufferSubDataParams final : public RenderTestParams
    {
        BufferSubDataParams()
        {
            // Common default values
            majorVersion      = 2;
            minorVersion      = 0;
            windowWidth       = 512;
            windowHeight      = 512;
            updateSize        = 32000;
            bufferSize        = 40000;
            iterationsPerStep = kIterationsPerStep;
            updateRate        = 1;
        }
    
        std::string story() const override;
    
        GLboolean vertexNormalized;
        GLenum vertexType;
        GLint vertexComponentCount;
        unsigned int updateRate;
    
        // static parameters
        GLsizeiptr updateSize;
        GLsizeiptr bufferSize;
    };
    
    std::ostream &operator<<(std::ostream &os, const BufferSubDataParams &params)
    {
        os << params.backendAndStory().substr(1);
        return os;
    }
    
    class BufferSubDataBenchmark : public ANGLERenderTest,
                                   public ::testing::WithParamInterface<BufferSubDataParams>
    {
      public:
        BufferSubDataBenchmark();
    
        void initializeBenchmark() override;
        void destroyBenchmark() override;
        void drawBenchmark() override;
    
      private:
        GLuint mProgram;
        GLuint mBuffer;
        uint8_t *mUpdateData;
        int mNumTris;
    };
    
    GLfloat *GetFloatData(GLint componentCount)
    {
        static GLfloat vertices2[] = {
            1, 2, 0, 0, 2, 0,
        };
    
        static GLfloat vertices3[] = {
            1, 2, 1, 0, 0, 1, 2, 0, 1,
        };
    
        static GLfloat vertices4[] = {
            1, 2, 1, 3, 0, 0, 1, 3, 2, 0, 1, 3,
        };
    
        switch (componentCount)
        {
            case 2:
                return vertices2;
            case 3:
                return vertices3;
            case 4:
                return vertices4;
            default:
                return nullptr;
        }
    }
    
    template <class T>
    GLsizeiptr GetNormalizedData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
    {
        GLsizeiptr triDataSize = sizeof(T) * numElements;
        data->resize(triDataSize);
    
        T *destPtr = reinterpret_cast<T *>(data->data());
    
        for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
        {
            GLfloat scaled = floatData[dataIndex] * 0.25f;
            destPtr[dataIndex] =
                static_cast<T>(scaled * static_cast<GLfloat>(std::numeric_limits<T>::max()));
        }
    
        return triDataSize;
    }
    
    template <class T>
    GLsizeiptr GetIntData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
    {
        GLsizeiptr triDataSize = sizeof(T) * numElements;
        data->resize(triDataSize);
    
        T *destPtr = reinterpret_cast<T *>(data->data());
    
        for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
        {
            destPtr[dataIndex] = static_cast<T>(floatData[dataIndex]);
        }
    
        return triDataSize;
    }
    
    GLsizeiptr GetVertexData(GLenum type,
                             GLint componentCount,
                             GLboolean normalized,
                             std::vector<uint8_t> *data)
    {
        GLsizeiptr triDataSize = 0;
        GLfloat *floatData     = GetFloatData(componentCount);
    
        if (type == GL_FLOAT)
        {
            triDataSize = sizeof(GLfloat) * componentCount * 3;
            data->resize(triDataSize);
            memcpy(data->data(), floatData, triDataSize);
        }
        else if (normalized == GL_TRUE)
        {
            GLsizeiptr numElements = componentCount * 3;
    
            switch (type)
            {
                case GL_BYTE:
                    triDataSize = GetNormalizedData<GLbyte>(numElements, floatData, data);
                    break;
                case GL_SHORT:
                    triDataSize = GetNormalizedData<GLshort>(numElements, floatData, data);
                    break;
                case GL_INT:
                    triDataSize = GetNormalizedData<GLint>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_BYTE:
                    triDataSize = GetNormalizedData<GLubyte>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_SHORT:
                    triDataSize = GetNormalizedData<GLushort>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_INT:
                    triDataSize = GetNormalizedData<GLuint>(numElements, floatData, data);
                    break;
                default:
                    assert(0);
            }
        }
        else
        {
            GLsizeiptr numElements = componentCount * 3;
    
            switch (type)
            {
                case GL_BYTE:
                    triDataSize = GetIntData<GLbyte>(numElements, floatData, data);
                    break;
                case GL_SHORT:
                    triDataSize = GetIntData<GLshort>(numElements, floatData, data);
                    break;
                case GL_INT:
                    triDataSize = GetIntData<GLint>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_BYTE:
                    triDataSize = GetIntData<GLubyte>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_SHORT:
                    triDataSize = GetIntData<GLushort>(numElements, floatData, data);
                    break;
                case GL_UNSIGNED_INT:
                    triDataSize = GetIntData<GLuint>(numElements, floatData, data);
                    break;
                default:
                    assert(0);
            }
        }
    
        return triDataSize;
    }
    
    std::string BufferSubDataParams::story() const
    {
        std::stringstream strstr;
    
        strstr << RenderTestParams::story();
    
        if (vertexNormalized)
        {
            strstr << "_norm";
        }
    
        switch (vertexType)
        {
            case GL_FLOAT:
                strstr << "_float";
                break;
            case GL_INT:
                strstr << "_int";
                break;
            case GL_BYTE:
                strstr << "_byte";
                break;
            case GL_SHORT:
                strstr << "_short";
                break;
            case GL_UNSIGNED_INT:
                strstr << "_uint";
                break;
            case GL_UNSIGNED_BYTE:
                strstr << "_ubyte";
                break;
            case GL_UNSIGNED_SHORT:
                strstr << "_ushort";
                break;
            default:
                strstr << "_vunk_" << vertexType << "_";
                break;
        }
    
        strstr << vertexComponentCount;
        strstr << "_every" << updateRate;
    
        return strstr.str();
    }
    
    BufferSubDataBenchmark::BufferSubDataBenchmark()
        : ANGLERenderTest("BufferSubData", GetParam()),
          mProgram(0),
          mBuffer(0),
          mUpdateData(nullptr),
          mNumTris(0)
    {}
    
    void BufferSubDataBenchmark::initializeBenchmark()
    {
        const auto &params = GetParam();
    
        ASSERT_LT(1, params.vertexComponentCount);
    
        mProgram = SetupSimpleScaleAndOffsetProgram();
        ASSERT_NE(0u, mProgram);
    
        if (params.vertexNormalized == GL_TRUE)
        {
            GLfloat scale  = 2.0f;
            GLfloat offset = -0.5f;
            glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
            glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
        }
    
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        std::vector<uint8_t> zeroData(params.bufferSize);
        memset(&zeroData[0], 0, zeroData.size());
    
        glGenBuffers(1, &mBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
        glBufferData(GL_ARRAY_BUFFER, params.bufferSize, &zeroData[0], GL_DYNAMIC_DRAW);
    
        glVertexAttribPointer(0, params.vertexComponentCount, params.vertexType,
                              params.vertexNormalized, 0, 0);
        glEnableVertexAttribArray(0);
    
        if (params.updateSize > 0)
        {
            mUpdateData = new uint8_t[params.updateSize];
        }
    
        std::vector<uint8_t> data;
        GLsizei triDataSize = static_cast<GLsizei>(GetVertexData(
            params.vertexType, params.vertexComponentCount, params.vertexNormalized, &data));
    
        mNumTris = static_cast<int>(params.updateSize / triDataSize);
        for (int i = 0, offset = 0; i < mNumTris; ++i)
        {
            memcpy(mUpdateData + offset, &data[0], triDataSize);
            offset += triDataSize;
        }
    
        if (params.updateSize == 0)
        {
            mNumTris = 1;
            glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), &data[0]);
        }
    
        // Set the viewport
        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
    
        ASSERT_GL_NO_ERROR();
    }
    
    void BufferSubDataBenchmark::destroyBenchmark()
    {
        glDeleteProgram(mProgram);
        glDeleteBuffers(1, &mBuffer);
        SafeDeleteArray(mUpdateData);
    }
    
    void BufferSubDataBenchmark::drawBenchmark()
    {
        glClear(GL_COLOR_BUFFER_BIT);
    
        const auto &params = GetParam();
    
        for (unsigned int it = 0; it < params.iterationsPerStep; it++)
        {
            if (params.updateSize > 0 && ((getNumStepsPerformed() % params.updateRate) == 0))
            {
                glBufferSubData(GL_ARRAY_BUFFER, 0, params.updateSize, mUpdateData);
            }
    
            glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris);
        }
    
        ASSERT_GL_NO_ERROR();
    }
    
    BufferSubDataParams BufferUpdateD3D11Params()
    {
        BufferSubDataParams params;
        params.eglParameters        = egl_platform::D3D11();
        params.vertexType           = GL_FLOAT;
        params.vertexComponentCount = 4;
        params.vertexNormalized     = GL_FALSE;
        return params;
    }
    
    BufferSubDataParams BufferUpdateOpenGLOrGLESParams()
    {
        BufferSubDataParams params;
        params.eglParameters        = egl_platform::OPENGL_OR_GLES();
        params.vertexType           = GL_FLOAT;
        params.vertexComponentCount = 4;
        params.vertexNormalized     = GL_FALSE;
        return params;
    }
    
    BufferSubDataParams BufferUpdateVulkanParams()
    {
        BufferSubDataParams params;
        params.eglParameters        = egl_platform::VULKAN();
        params.vertexType           = GL_FLOAT;
        params.vertexComponentCount = 4;
        params.vertexNormalized     = GL_FALSE;
        return params;
    }
    
    TEST_P(BufferSubDataBenchmark, Run)
    {
        run();
    }
    
    ANGLE_INSTANTIATE_TEST(BufferSubDataBenchmark,
                           BufferUpdateD3D11Params(),
                           BufferUpdateOpenGLOrGLESParams(),
                           BufferUpdateVulkanParams());
    
    }  // namespace