Path: blob/main_old/src/tests/perf_tests/DrawElementsPerf.cpp
1693 views
//1// Copyright 2017 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// DrawElementsPerf:6// Performance tests for ANGLE DrawElements call overhead.7//89#include <sstream>1011#include "ANGLEPerfTest.h"12#include "DrawCallPerfParams.h"13#include "test_utils/draw_call_perf_utils.h"1415namespace16{1718GLuint CreateElementArrayBuffer(size_t count, GLenum type, GLenum usage)19{20GLuint buffer = 0u;21glGenBuffers(1, &buffer);22glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);23glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(type), nullptr, usage);2425return buffer;26}2728struct DrawElementsPerfParams final : public DrawCallPerfParams29{30// Common default options31DrawElementsPerfParams()32{33runTimeSeconds = 5.0;34numTris = 2;35}3637std::string story() const override38{39std::stringstream strstr;4041strstr << DrawCallPerfParams::story();4243if (indexBufferChanged)44{45strstr << "_index_buffer_changed";46}4748if (type == GL_UNSIGNED_SHORT)49{50strstr << "_ushort";51}5253return strstr.str();54}5556GLenum type = GL_UNSIGNED_INT;57bool indexBufferChanged = false;58};5960std::ostream &operator<<(std::ostream &os, const DrawElementsPerfParams ¶ms)61{62os << params.backendAndStory().substr(1);63return os;64}6566class DrawElementsPerfBenchmark : public ANGLERenderTest,67public ::testing::WithParamInterface<DrawElementsPerfParams>68{69public:70DrawElementsPerfBenchmark();7172void initializeBenchmark() override;73void destroyBenchmark() override;74void drawBenchmark() override;7576private:77GLuint mProgram = 0;78GLuint mBuffer = 0;79GLuint mIndexBuffer = 0;80GLuint mFBO = 0;81GLuint mTexture = 0;82GLsizei mBufferSize = 0;83int mCount = 3 * GetParam().numTris;84std::vector<GLuint> mIntIndexData;85std::vector<GLushort> mShortIndexData;86};8788DrawElementsPerfBenchmark::DrawElementsPerfBenchmark()89: ANGLERenderTest("DrawElementsPerf", GetParam())90{91if (GetParam().type == GL_UNSIGNED_INT)92{93addExtensionPrerequisite("GL_OES_element_index_uint");94}95}9697GLsizei ElementTypeSize(GLenum elementType)98{99switch (elementType)100{101case GL_UNSIGNED_BYTE:102return sizeof(GLubyte);103case GL_UNSIGNED_SHORT:104return sizeof(GLushort);105case GL_UNSIGNED_INT:106return sizeof(GLuint);107default:108return 0;109}110}111112void DrawElementsPerfBenchmark::initializeBenchmark()113{114const auto ¶ms = GetParam();115116mProgram = SetupSimpleDrawProgram();117ASSERT_NE(0u, mProgram);118119glClearColor(0.0f, 0.0f, 0.0f, 0.0f);120121mBuffer = Create2DTriangleBuffer(params.numTris, GL_STATIC_DRAW);122mIndexBuffer = CreateElementArrayBuffer(mCount, params.type, GL_STATIC_DRAW);123124for (int i = 0; i < mCount; i++)125{126ASSERT_GE(std::numeric_limits<GLushort>::max(), mCount);127mShortIndexData.push_back(static_cast<GLushort>(rand() % mCount));128mIntIndexData.push_back(rand() % mCount);129}130131glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);132133mBufferSize = ElementTypeSize(params.type) * mCount;134135if (params.type == GL_UNSIGNED_INT)136{137glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mIntIndexData.data());138}139else140{141glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, mShortIndexData.data());142}143144glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);145glEnableVertexAttribArray(0);146147// Set the viewport148glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());149150if (params.surfaceType == SurfaceType::Offscreen)151{152CreateColorFBO(getWindow()->getWidth(), getWindow()->getHeight(), &mTexture, &mFBO);153}154155ASSERT_GL_NO_ERROR();156}157158void DrawElementsPerfBenchmark::destroyBenchmark()159{160glDeleteProgram(mProgram);161glDeleteBuffers(1, &mBuffer);162glDeleteBuffers(1, &mIndexBuffer);163glDeleteTextures(1, &mTexture);164glDeleteFramebuffers(1, &mFBO);165}166167void DrawElementsPerfBenchmark::drawBenchmark()168{169// This workaround fixes a huge queue of graphics commands accumulating on the GL170// back-end. The GL back-end doesn't have a proper NULL device at the moment.171// TODO(jmadill): Remove this when/if we ever get a proper OpenGL NULL device.172const auto &eglParams = GetParam().eglParameters;173if (eglParams.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE ||174(eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE &&175eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))176{177glClear(GL_COLOR_BUFFER_BIT);178}179180const DrawElementsPerfParams ¶ms = GetParam();181182if (params.indexBufferChanged)183{184const void *bufferData = (params.type == GL_UNSIGNED_INT)185? static_cast<GLvoid *>(mIntIndexData.data())186: static_cast<GLvoid *>(mShortIndexData.data());187for (unsigned int it = 0; it < params.iterationsPerStep; it++)188{189glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mBufferSize, bufferData);190glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCount), params.type, 0);191}192}193else194{195for (unsigned int it = 0; it < params.iterationsPerStep; it++)196{197glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mCount), params.type, 0);198}199}200201ASSERT_GL_NO_ERROR();202}203204TEST_P(DrawElementsPerfBenchmark, Run)205{206run();207}208209using namespace angle;210using namespace params;211using P = DrawElementsPerfParams;212213P CombineIndexType(const P &in, GLenum indexType)214{215P out = in;216out.type = indexType;217return out;218}219220P CombineIndexBufferChanged(const P &in, bool indexBufferChanged)221{222P out = in;223out.indexBufferChanged = indexBufferChanged;224225// Scale down iterations for slower tests.226if (indexBufferChanged)227out.iterationsPerStep /= 100;228229return out;230}231232std::vector<GLenum> gIndexTypes = {GL_UNSIGNED_INT, GL_UNSIGNED_SHORT};233std::vector<P> gWithIndexType = CombineWithValues({P()}, gIndexTypes, CombineIndexType);234std::vector<P> gWithRenderer =235CombineWithFuncs(gWithIndexType, {D3D11<P>, GL<P>, Vulkan<P>, WGL<P>});236std::vector<P> gWithChange =237CombineWithValues(gWithRenderer, {false, true}, CombineIndexBufferChanged);238std::vector<P> gWithDevice = CombineWithFuncs(gWithChange, {Passthrough<P>, NullDevice<P>});239240ANGLE_INSTANTIATE_TEST_ARRAY(DrawElementsPerfBenchmark, gWithDevice);241242} // anonymous namespace243244245