Edit

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

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2021-09-17 11:45:01
    Hash : 3e234e24
    Message : PerfTests: Updates to several tests. Bug: angleproject:6371 Change-Id: If71c79fd363f7463098b571550af6ceb0634c00d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3176440 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com>

  • src/tests/perf_tests/VertexArrayPerfTest.cpp
  • //
    // Copyright 2021 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.
    //
    // VertexArrayPerfTest:
    //   Performance test for glBindVertexArray.
    //
    
    #include "ANGLEPerfTest.h"
    #include "DrawCallPerfParams.h"
    #include "test_utils/gl_raii.h"
    
    using namespace angle;
    
    namespace
    {
    enum class TestMode
    {
        BufferData,
        BindBuffer,
    };
    
    struct VertexArrayParams final : public RenderTestParams
    {
        VertexArrayParams()
        {
            iterationsPerStep = 1;
    
            // Common default params
            majorVersion = 3;
            minorVersion = 0;
            windowWidth  = 720;
            windowHeight = 720;
        }
    
        std::string story() const override;
    
        int numVertexArrays = 1000;
        int numBuffers      = 5;
        TestMode testMode   = TestMode::BufferData;
    };
    
    std::ostream &operator<<(std::ostream &os, const VertexArrayParams &params)
    {
        os << params.backendAndStory().substr(1);
        return os;
    }
    
    std::string VertexArrayParams::story() const
    {
        std::stringstream strstr;
    
        strstr << RenderTestParams::story();
    
        if (testMode == TestMode::BindBuffer)
        {
            strstr << "_bindbuffer";
        }
    
        return strstr.str();
    }
    
    class VertexArrayBenchmark : public ANGLERenderTest,
                                 public ::testing::WithParamInterface<VertexArrayParams>
    {
      public:
        VertexArrayBenchmark();
    
        void initializeBenchmark() override;
        void destroyBenchmark() override;
        void drawBenchmark() override;
    
        void rebindVertexArray(GLuint vertexArrayID, GLuint bufferID);
    
      private:
        std::vector<GLuint> mBuffers;
        GLuint mProgram       = 0;
        GLint mAttribLocation = 0;
        std::vector<GLuint> mVertexArrays;
    };
    
    VertexArrayBenchmark::VertexArrayBenchmark() : ANGLERenderTest("VertexArrayPerf", GetParam()) {}
    
    void VertexArrayBenchmark::initializeBenchmark()
    {
        constexpr char kVS[] = R"(attribute vec4 position;
    attribute float in_attrib;
    varying float v_attrib;
    void main()
    {
        v_attrib = in_attrib;
        gl_Position = position;
    })";
    
        constexpr char kFS[] = R"(precision mediump float;
    varying float v_attrib;
    void main()
    {
        gl_FragColor = vec4(v_attrib, 0, 0, 1);
    })";
    
        mProgram = CompileProgram(kVS, kFS);
        ASSERT_NE(0u, mProgram);
    
        mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
        ASSERT_NE(mAttribLocation, -1);
    
        // Generate 5 buffers.
        int numBuffers = GetParam().numBuffers;
        mBuffers.resize(numBuffers, 0);
        glGenBuffers(numBuffers, mBuffers.data());
    
        int numVertexArrays = GetParam().numVertexArrays;
        mVertexArrays.resize(numVertexArrays, 0);
        glGenVertexArrays(numVertexArrays, mVertexArrays.data());
    
        // Bind one VBO to all VAOs.
        for (GLuint vertexArray : mVertexArrays)
        {
            rebindVertexArray(vertexArray, mBuffers[0]);
        }
    
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
    }
    
    void VertexArrayBenchmark::rebindVertexArray(GLuint vertexArrayID, GLuint bufferID)
    {
        // Rebind a vertex array object and a generic vertex attribute inside of it.
        glBindVertexArray(vertexArrayID);
        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
        glEnableVertexAttribArray(mAttribLocation);
        glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
        glVertexAttribDivisor(mAttribLocation, 1);
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
    
    void VertexArrayBenchmark::destroyBenchmark()
    {
        glDeleteProgram(mProgram);
        glDeleteVertexArrays(static_cast<GLsizei>(mVertexArrays.size()), mVertexArrays.data());
        mVertexArrays.clear();
        glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
        mBuffers.clear();
    }
    
    void VertexArrayBenchmark::drawBenchmark()
    {
        const VertexArrayParams &params = GetParam();
        if (params.testMode == TestMode::BufferData)
        {
            glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_STATIC_DRAW);
        }
        else
        {
            int bufferIndex = 0;
            for (GLuint vertexArray : mVertexArrays)
            {
                bufferIndex = ((bufferIndex + 1) == params.numBuffers) ? 0 : (bufferIndex + 1);
                rebindVertexArray(vertexArray, mBuffers[bufferIndex]);
            }
        }
    }
    
    TEST_P(VertexArrayBenchmark, Run)
    {
        run();
    }
    
    VertexArrayParams VulkanParams()
    {
        VertexArrayParams params;
        params.eglParameters = egl_platform::VULKAN();
        return params;
    }
    
    VertexArrayParams VulkanNullParams(TestMode testMode)
    {
        VertexArrayParams params;
        params.eglParameters = egl_platform::VULKAN_NULL();
        params.testMode      = testMode;
        return params;
    }
    
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexArrayBenchmark);
    ANGLE_INSTANTIATE_TEST(VertexArrayBenchmark,
                           VulkanParams(),
                           VulkanNullParams(TestMode::BindBuffer),
                           VulkanNullParams(TestMode::BufferData),
                           params::Native(VertexArrayParams()));
    }  // namespace