Edit

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

Branch :

  • Show log

    Commit

  • Author : Austin Sullivan
    Date : 2021-02-18 18:21:32
    Hash : fd132e4e
    Message : testing: Mark uninstantiated perftests googletest CL 315255779 causes test binaries to fail when they include test suites / parametrized tests that are not instantiated, and when they include empty test suites. This CL uses the GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST() macro to annotate the suites / tests that are causing test failures. This is necessary to get googletest rolled past CL 315255779. Bug: chromium:1163396 Change-Id: I13ffa09c4263a6dc8baf1749c3df5d2c54904e68 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2704800 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/tests/perf_tests/IndexConversionPerf.cpp
  • //
    // Copyright 2015 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.
    //
    // IndexConversionPerf:
    //   Performance tests for ANGLE index conversion in D3D11.
    //
    
    #include "ANGLEPerfTest.h"
    #include "tests/test_utils/draw_call_perf_utils.h"
    
    #include <sstream>
    
    using namespace angle;
    
    namespace
    {
    struct IndexConversionPerfParams final : public RenderTestParams
    {
        std::string story() const override
        {
            std::stringstream strstr;
    
            if (indexRangeOffset > 0)
            {
                strstr << "_index_range";
            }
    
            strstr << RenderTestParams::story();
    
            return strstr.str();
        }
    
        unsigned int numIndexTris;
    
        // A second test, which covers using index ranges with an offset.
        unsigned int indexRangeOffset;
    };
    
    // Provide a custom gtest parameter name function for IndexConversionPerfParams.
    std::ostream &operator<<(std::ostream &stream, const IndexConversionPerfParams &param)
    {
        stream << param.backendAndStory().substr(1);
        return stream;
    }
    
    class IndexConversionPerfTest : public ANGLERenderTest,
                                    public ::testing::WithParamInterface<IndexConversionPerfParams>
    {
      public:
        IndexConversionPerfTest();
    
        void initializeBenchmark() override;
        void destroyBenchmark() override;
        void drawBenchmark() override;
    
      private:
        void updateBufferData();
        void drawConversion();
        void drawIndexRange();
    
        GLuint mProgram;
        GLuint mVertexBuffer;
        GLuint mIndexBuffer;
        std::vector<GLushort> mIndexData;
    };
    
    IndexConversionPerfTest::IndexConversionPerfTest()
        : ANGLERenderTest("IndexConversionPerfTest", GetParam()),
          mProgram(0),
          mVertexBuffer(0),
          mIndexBuffer(0)
    {}
    
    void IndexConversionPerfTest::initializeBenchmark()
    {
        const auto &params = GetParam();
    
        ASSERT_LT(0u, params.iterationsPerStep);
        ASSERT_LT(0u, params.numIndexTris);
    
        mProgram = SetupSimpleScaleAndOffsetProgram();
        ASSERT_NE(0u, mProgram);
    
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        // Initialize the vertex data
        size_t numTris = std::numeric_limits<GLushort>::max() / 3 + 1;
        mVertexBuffer  = Create2DTriangleBuffer(numTris, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
    
        // Initialize the index buffer
        for (unsigned int triIndex = 0; triIndex < params.numIndexTris; ++triIndex)
        {
            // Handle two different types of tests, one with index conversion triggered by a -1 index.
            if (params.indexRangeOffset == 0)
            {
                mIndexData.push_back(std::numeric_limits<GLushort>::max());
            }
            else
            {
                mIndexData.push_back(0);
            }
    
            mIndexData.push_back(1);
            mIndexData.push_back(2);
        }
    
        glGenBuffers(1, &mIndexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        updateBufferData();
    
        // Set the viewport
        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
    
        ASSERT_GL_NO_ERROR();
    }
    
    void IndexConversionPerfTest::updateBufferData()
    {
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexData.size() * sizeof(mIndexData[0]), &mIndexData[0],
                     GL_STATIC_DRAW);
    }
    
    void IndexConversionPerfTest::destroyBenchmark()
    {
        glDeleteProgram(mProgram);
        glDeleteBuffers(1, &mVertexBuffer);
        glDeleteBuffers(1, &mIndexBuffer);
    }
    
    void IndexConversionPerfTest::drawBenchmark()
    {
        const auto &params = GetParam();
    
        if (params.indexRangeOffset == 0)
        {
            drawConversion();
        }
        else
        {
            drawIndexRange();
        }
    }
    
    void IndexConversionPerfTest::drawConversion()
    {
        const auto &params = GetParam();
    
        // Trigger an update to ensure we convert once a frame
        updateBufferData();
    
        for (unsigned int it = 0; it < params.iterationsPerStep; it++)
        {
            glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(params.numIndexTris * 3 - 1),
                           GL_UNSIGNED_SHORT, reinterpret_cast<void *>(0));
        }
    
        ASSERT_GL_NO_ERROR();
    }
    
    void IndexConversionPerfTest::drawIndexRange()
    {
        const auto &params = GetParam();
    
        unsigned int indexCount = 3;
        size_t offset           = static_cast<size_t>(indexCount * getNumStepsPerformed());
    
        offset %= (params.numIndexTris * 3);
    
        // This test increments an offset each step. Drawing repeatedly may cause the system memory
        // to release. Then, using a fresh offset will require index range validation, which pages
        // it back in. The performance should be good even if the data is was used quite a bit.
        for (unsigned int it = 0; it < params.iterationsPerStep; it++)
        {
            glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indexCount), GL_UNSIGNED_SHORT,
                           reinterpret_cast<void *>(offset));
        }
    
        ASSERT_GL_NO_ERROR();
    }
    
    IndexConversionPerfParams IndexConversionPerfD3D11Params()
    {
        IndexConversionPerfParams params;
        params.eglParameters     = egl_platform::D3D11_NULL();
        params.majorVersion      = 2;
        params.minorVersion      = 0;
        params.windowWidth       = 256;
        params.windowHeight      = 256;
        params.iterationsPerStep = 225;
        params.numIndexTris      = 3000;
        params.indexRangeOffset  = 0;
        return params;
    }
    
    IndexConversionPerfParams IndexRangeOffsetPerfD3D11Params()
    {
        IndexConversionPerfParams params;
        params.eglParameters     = egl_platform::D3D11_NULL();
        params.majorVersion      = 2;
        params.minorVersion      = 0;
        params.windowWidth       = 256;
        params.windowHeight      = 256;
        params.iterationsPerStep = 16;
        params.numIndexTris      = 50000;
        params.indexRangeOffset  = 64;
        return params;
    }
    
    TEST_P(IndexConversionPerfTest, Run)
    {
        run();
    }
    
    ANGLE_INSTANTIATE_TEST(IndexConversionPerfTest,
                           IndexConversionPerfD3D11Params(),
                           IndexRangeOffsetPerfD3D11Params());
    
    // This test suite is not instantiated on some OSes.
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IndexConversionPerfTest);
    }  // namespace