Edit

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

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2015-04-15 14:26:37
    Hash : b48e8b07
    Message : D3D11: Only rewrite for primitive restart when needed. We would rewrite our index data every draw call. Change the index check to see if we're writing to the same sized / typed static buffer and only rewrite the data if the user re-uploaded. Also add a performance test for the primitive restart workaround. As a future improvement we could avoid creating new D3D objects every time we reinitialize static data, since BufferSubData calls don't change the size of the buffer if the index type remains the same. BUG=476658 Change-Id: I9d2540ad8b1b34fa0142ba0bf794cf572da8c61d Reviewed-on: https://chromium-review.googlesource.com/265838 Tested-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Brandon Jones <bajones@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 <sstream>
    
    #include "ANGLEPerfTest.h"
    #include "shader_utils.h"
    
    namespace
    {
    
    struct IndexConversionPerfParams final : public RenderTestParams
    {
        std::string suffix() const override
        {
            std::stringstream strstr;
    
            strstr << RenderTestParams::suffix();
    
            return strstr.str();
        }
    
        unsigned int iterations;
        unsigned int numIndexTris;
    };
    
    class IndexConversionPerfTest : public ANGLERenderTest,
                                    public ::testing::WithParamInterface<IndexConversionPerfParams>
    {
      public:
        IndexConversionPerfTest();
    
        void initializeBenchmark() override;
        void destroyBenchmark() override;
        void beginDrawBenchmark() override;
        void drawBenchmark() override;
    
        void updateBufferData();
    
      private:
        GLuint mProgram;
        GLuint mVertexBuffer;
        GLuint mIndexBuffer;
        std::vector<GLushort> mIndexData;
    };
    
    IndexConversionPerfTest::IndexConversionPerfTest()
        : ANGLERenderTest("IndexConversionPerfTest", GetParam()),
          mProgram(0),
          mVertexBuffer(0),
          mIndexBuffer(0)
    {
        mRunTimeSeconds = 3.0;
    }
    
    void IndexConversionPerfTest::initializeBenchmark()
    {
        const auto &params = GetParam();
    
        ASSERT_TRUE(params.iterations > 0);
        ASSERT_TRUE(params.numIndexTris > 0);
    
        mDrawIterations = params.iterations;
    
        const std::string vs = SHADER_SOURCE
        (
            attribute vec2 vPosition;
            uniform float uScale;
            uniform float uOffset;
            void main()
            {
                gl_Position = vec4(vPosition * vec2(uScale) - vec2(uOffset), 0, 1);
            }
        );
    
        const std::string fs = SHADER_SOURCE
        (
            precision mediump float;
            void main()
            {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        );
    
        mProgram = CompileProgram(vs, fs);
        ASSERT_TRUE(mProgram != 0);
    
        // Use the program object
        glUseProgram(mProgram);
    
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        // Initialize the vertex data
        std::vector<GLfloat> floatData;
    
        size_t numTris = std::numeric_limits<GLushort>::max() / 3 + 1;
        for (size_t triIndex = 0; triIndex < numTris; ++triIndex)
        {
            floatData.push_back(1);
            floatData.push_back(2);
            floatData.push_back(0);
            floatData.push_back(0);
            floatData.push_back(2);
            floatData.push_back(0);
        }
    
        glGenBuffers(1, &mVertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, floatData.size() * sizeof(GLfloat), &floatData[0], 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)
        {
            mIndexData.push_back(std::numeric_limits<GLushort>::max());
            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());
    
        GLfloat scale = 0.5f;
        GLfloat offset = 0.5f;
    
        glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
        glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
    
        ASSERT_TRUE(glGetError() == 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::beginDrawBenchmark()
    {
        // Clear the color buffer
        glClear(GL_COLOR_BUFFER_BIT);
    }
    
    void IndexConversionPerfTest::drawBenchmark()
    {
        const auto &params = GetParam();
    
        // Trigger an update to ensure we convert once a frame
        updateBufferData();
    
        for (unsigned int it = 0; it < params.iterations; it++)
        {
            glDrawElements(GL_TRIANGLES,
                           static_cast<GLsizei>(params.numIndexTris * 3 - 1),
                           GL_UNSIGNED_SHORT,
                           reinterpret_cast<GLvoid*>(0));
        }
    
        EXPECT_TRUE(glGetError() == GL_NO_ERROR);
    }
    
    IndexConversionPerfParams IndexConversionPerfD3D11Params()
    {
        IndexConversionPerfParams params;
        params.glesMajorVersion = 2;
        params.widowWidth = 256;
        params.windowHeight = 256;
        params.requestedRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
        params.deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE;
        params.iterations = 15;
        params.numIndexTris = 3000;
        return params;
    }
    
    TEST_P(IndexConversionPerfTest, Run)
    {
        run();
    }
    
    INSTANTIATE_TEST_CASE_P(IndexConversionPerf,
                            IndexConversionPerfTest,
                            ::testing::Values(IndexConversionPerfD3D11Params()));
    
    } // namespace