Path: blob/main_old/src/tests/perf_tests/BindingPerf.cpp
1693 views
//1// Copyright 2016 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// BindingPerf:6// Performance test for binding objects7//89#include "ANGLEPerfTest.h"1011#include <iostream>12#include <random>13#include <sstream>1415#include "test_utils/angle_test_instantiate.h"16#include "util/shader_utils.h"1718namespace angle19{20constexpr unsigned int kIterationsPerStep = 128;2122enum AllocationStyle23{24EVERY_ITERATION,25AT_INITIALIZATION26};2728struct BindingsParams final : public RenderTestParams29{30BindingsParams()31{32// Common default params33majorVersion = 2;34minorVersion = 0;35windowWidth = 720;36windowHeight = 720;3738numObjects = 100;39allocationStyle = EVERY_ITERATION;40iterationsPerStep = kIterationsPerStep;41}4243std::string story() const override;44size_t numObjects;45AllocationStyle allocationStyle;46};4748std::ostream &operator<<(std::ostream &os, const BindingsParams ¶ms)49{50os << params.backendAndStory().substr(1);51return os;52}5354std::string BindingsParams::story() const55{56std::stringstream strstr;5758strstr << RenderTestParams::story();59strstr << "_" << numObjects << "_objects";6061switch (allocationStyle)62{63case EVERY_ITERATION:64strstr << "_allocated_every_iteration";65break;66case AT_INITIALIZATION:67strstr << "_allocated_at_initialization";68break;69default:70strstr << "_err";71break;72}7374return strstr.str();75}7677class BindingsBenchmark : public ANGLERenderTest,78public ::testing::WithParamInterface<BindingsParams>79{80public:81BindingsBenchmark();8283void initializeBenchmark() override;84void destroyBenchmark() override;85void drawBenchmark() override;8687private:88// TODO: Test binding perf of more than just buffers89std::vector<GLuint> mBuffers;90std::vector<GLenum> mBindingPoints;91};9293BindingsBenchmark::BindingsBenchmark() : ANGLERenderTest("Bindings", GetParam())94{95// Flaky on OpenGL. http://anglebug.com/626496if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)97{98mSkipTest = true;99}100}101102void BindingsBenchmark::initializeBenchmark()103{104const auto ¶ms = GetParam();105106mBuffers.resize(params.numObjects, 0);107if (params.allocationStyle == AT_INITIALIZATION)108{109glGenBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());110for (size_t bufferIdx = 0; bufferIdx < mBuffers.size(); bufferIdx++)111{112glBindBuffer(GL_ARRAY_BUFFER, mBuffers[bufferIdx]);113}114glBindBuffer(GL_ARRAY_BUFFER, 0);115}116117mBindingPoints.push_back(GL_ARRAY_BUFFER);118mBindingPoints.push_back(GL_ELEMENT_ARRAY_BUFFER);119if (params.majorVersion >= 3)120{121mBindingPoints.push_back(GL_PIXEL_PACK_BUFFER);122mBindingPoints.push_back(GL_PIXEL_UNPACK_BUFFER);123mBindingPoints.push_back(GL_COPY_READ_BUFFER);124mBindingPoints.push_back(GL_COPY_WRITE_BUFFER);125mBindingPoints.push_back(GL_TRANSFORM_FEEDBACK_BUFFER);126mBindingPoints.push_back(GL_UNIFORM_BUFFER);127}128if (params.majorVersion > 3 || (params.majorVersion == 3 && params.minorVersion >= 1))129{130mBindingPoints.push_back(GL_ATOMIC_COUNTER_BUFFER);131mBindingPoints.push_back(GL_SHADER_STORAGE_BUFFER);132mBindingPoints.push_back(GL_DRAW_INDIRECT_BUFFER);133mBindingPoints.push_back(GL_DISPATCH_INDIRECT_BUFFER);134}135}136137void BindingsBenchmark::destroyBenchmark()138{139const auto ¶ms = GetParam();140if (params.allocationStyle == AT_INITIALIZATION)141{142glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());143}144}145146void BindingsBenchmark::drawBenchmark()147{148const auto ¶ms = GetParam();149150for (unsigned int it = 0; it < params.iterationsPerStep; ++it)151{152// Generate a buffer (if needed) and bind it to a "random" binding point153if (params.allocationStyle == EVERY_ITERATION)154{155glGenBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());156}157158// Fetch a few variables from the underlying data structure to keep them in registers.159// Otherwise each loop iteration they'll be fetched again because the compiler cannot160// guarantee that those are unchanged when calling glBindBuffer.161unsigned int *buffers = mBuffers.data();162unsigned int *bindingPoints = mBindingPoints.data();163size_t bindingPointsSize = mBindingPoints.size();164size_t buffersSize = mBuffers.size();165size_t bindingIndex = it % bindingPointsSize;166for (size_t bufferIdx = 0; bufferIdx < buffersSize; bufferIdx++)167{168GLenum binding = bindingPoints[bindingIndex];169glBindBuffer(binding, buffers[bufferIdx]);170171// Instead of doing a costly division to get an index in the range [0,bindingPointsSize)172// do a bounds-check and reset the index.173++bindingIndex;174bindingIndex = (bindingIndex >= bindingPointsSize) ? 0 : bindingIndex;175}176177// Delete all the buffers178if (params.allocationStyle == EVERY_ITERATION)179{180glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());181}182}183184ASSERT_GL_NO_ERROR();185}186187BindingsParams D3D11Params(AllocationStyle allocationStyle)188{189BindingsParams params;190params.eglParameters = egl_platform::D3D11_NULL();191params.allocationStyle = allocationStyle;192return params;193}194195BindingsParams OpenGLOrGLESParams(AllocationStyle allocationStyle)196{197BindingsParams params;198params.eglParameters = egl_platform::OPENGL_OR_GLES_NULL();199params.allocationStyle = allocationStyle;200return params;201}202203BindingsParams VulkanParams(AllocationStyle allocationStyle)204{205BindingsParams params;206params.eglParameters = egl_platform::VULKAN_NULL();207params.allocationStyle = allocationStyle;208return params;209}210211TEST_P(BindingsBenchmark, Run)212{213run();214}215216ANGLE_INSTANTIATE_TEST(BindingsBenchmark,217D3D11Params(EVERY_ITERATION),218D3D11Params(AT_INITIALIZATION),219OpenGLOrGLESParams(EVERY_ITERATION),220OpenGLOrGLESParams(AT_INITIALIZATION),221VulkanParams(EVERY_ITERATION),222VulkanParams(AT_INITIALIZATION));223224} // namespace angle225226227