Path: blob/main_old/src/tests/perf_tests/TexturesPerf.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// TexturesPerf:6// Performance test for setting texture state.7//89#include "ANGLEPerfTest.h"1011#include <iostream>12#include <random>13#include <sstream>1415#include "util/shader_utils.h"1617namespace angle18{19constexpr unsigned int kIterationsPerStep = 256;2021struct TexturesParams final : public RenderTestParams22{23TexturesParams()24{25iterationsPerStep = kIterationsPerStep;2627// Common default params28majorVersion = 2;29minorVersion = 0;30windowWidth = 720;31windowHeight = 720;3233numTextures = 8;34textureRebindFrequency = 5;35textureStateUpdateFrequency = 3;36textureMipCount = 8;3738webgl = false;39}4041std::string story() const override;42size_t numTextures;43size_t textureRebindFrequency;44size_t textureStateUpdateFrequency;45size_t textureMipCount;4647bool webgl;48};4950std::ostream &operator<<(std::ostream &os, const TexturesParams ¶ms)51{52os << params.backendAndStory().substr(1);53return os;54}5556std::string TexturesParams::story() const57{58std::stringstream strstr;5960strstr << RenderTestParams::story();61strstr << "_" << numTextures << "_textures";62strstr << "_" << textureRebindFrequency << "_rebind";63strstr << "_" << textureStateUpdateFrequency << "_state";64strstr << "_" << textureMipCount << "_mips";6566if (webgl)67{68strstr << "_webgl";69}7071return strstr.str();72}7374class TexturesBenchmark : public ANGLERenderTest,75public ::testing::WithParamInterface<TexturesParams>76{77public:78TexturesBenchmark();7980void initializeBenchmark() override;81void destroyBenchmark() override;82void drawBenchmark() override;8384private:85void initShaders();86void initTextures();8788std::vector<GLuint> mTextures;8990GLuint mProgram;91std::vector<GLuint> mUniformLocations;92};9394TexturesBenchmark::TexturesBenchmark() : ANGLERenderTest("Textures", GetParam()), mProgram(0u)95{96setWebGLCompatibilityEnabled(GetParam().webgl);97setRobustResourceInit(GetParam().webgl);98}99100void TexturesBenchmark::initializeBenchmark()101{102const auto ¶ms = GetParam();103104// Verify the uniform counts are within the limits105GLint maxTextureUnits;106glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);107if (params.numTextures > static_cast<size_t>(maxTextureUnits))108{109FAIL() << "Texture count (" << params.numTextures << ")"110<< " exceeds maximum texture unit count: " << maxTextureUnits << std::endl;111}112113initShaders();114initTextures();115glClearColor(0.0f, 0.0f, 0.0f, 0.0f);116glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());117118ASSERT_GL_NO_ERROR();119}120121std::string GetUniformLocationName(size_t idx, bool vertexShader)122{123std::stringstream strstr;124strstr << (vertexShader ? "vs" : "fs") << "_u_" << idx;125return strstr.str();126}127128void TexturesBenchmark::initShaders()129{130const auto ¶ms = GetParam();131132std::string vs =133"void main()\n"134"{\n"135" gl_Position = vec4(0, 0, 0, 0);\n"136"}\n";137138std::stringstream fstrstr;139for (size_t i = 0; i < params.numTextures; i++)140{141fstrstr << "uniform sampler2D tex" << i << ";";142}143fstrstr << "void main()\n"144"{\n"145" gl_FragColor = vec4(0, 0, 0, 0)";146for (size_t i = 0; i < params.numTextures; i++)147{148fstrstr << "+ texture2D(tex" << i << ", vec2(0, 0))";149}150fstrstr << ";\n"151"}\n";152153mProgram = CompileProgram(vs.c_str(), fstrstr.str().c_str());154ASSERT_NE(0u, mProgram);155156for (size_t i = 0; i < params.numTextures; ++i)157{158std::stringstream uniformName;159uniformName << "tex" << i;160161GLint location = glGetUniformLocation(mProgram, uniformName.str().c_str());162ASSERT_NE(-1, location);163mUniformLocations.push_back(location);164}165166// Use the program object167glUseProgram(mProgram);168}169170void TexturesBenchmark::initTextures()171{172const auto ¶ms = GetParam();173174size_t textureSize = static_cast<size_t>(1) << params.textureMipCount;175std::vector<GLubyte> textureData(textureSize * textureSize * 4);176for (auto &byte : textureData)177{178byte = rand() % 255u;179}180181for (size_t texIndex = 0; texIndex < params.numTextures; texIndex++)182{183GLuint tex = 0;184glGenTextures(1, &tex);185186glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + texIndex));187glBindTexture(GL_TEXTURE_2D, tex);188for (size_t mip = 0; mip < params.textureMipCount; mip++)189{190GLsizei levelSize = static_cast<GLsizei>(textureSize >> mip);191glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(mip), GL_RGBA, levelSize, levelSize, 0,192GL_RGBA, GL_UNSIGNED_BYTE, textureData.data());193}194mTextures.push_back(tex);195196glUniform1i(mUniformLocations[texIndex], static_cast<GLint>(texIndex));197}198}199200void TexturesBenchmark::destroyBenchmark()201{202glDeleteProgram(mProgram);203}204205void TexturesBenchmark::drawBenchmark()206{207const auto ¶ms = GetParam();208209for (size_t it = 0; it < params.iterationsPerStep; ++it)210{211if (it % params.textureRebindFrequency == 0)212{213// Swap two textures214size_t swapTexture = (it / params.textureRebindFrequency) % (params.numTextures - 1);215216glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + swapTexture));217glBindTexture(GL_TEXTURE_2D, mTextures[swapTexture]);218glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + swapTexture + 1));219glBindTexture(GL_TEXTURE_2D, mTextures[swapTexture + 1]);220std::swap(mTextures[swapTexture], mTextures[swapTexture + 1]);221}222223if (it % params.textureStateUpdateFrequency == 0)224{225// Update a texture's state226size_t stateUpdateCount = it / params.textureStateUpdateFrequency;227228const size_t numUpdateTextures = 4;229ASSERT_LE(numUpdateTextures, params.numTextures);230231size_t firstTexture = stateUpdateCount % (params.numTextures - numUpdateTextures);232233for (size_t updateTextureIdx = 0; updateTextureIdx < numUpdateTextures;234updateTextureIdx++)235{236size_t updateTexture = firstTexture + updateTextureIdx;237glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + updateTexture));238239const GLenum minFilters[] = {240GL_NEAREST,241GL_LINEAR,242GL_NEAREST_MIPMAP_NEAREST,243GL_LINEAR_MIPMAP_NEAREST,244GL_NEAREST_MIPMAP_LINEAR,245GL_LINEAR_MIPMAP_LINEAR,246};247glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,248minFilters[stateUpdateCount % ArraySize(minFilters)]);249250const GLenum magFilters[] = {251GL_NEAREST,252GL_LINEAR,253};254glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,255magFilters[stateUpdateCount % ArraySize(magFilters)]);256257const GLenum wrapParameters[] = {258GL_CLAMP_TO_EDGE,259GL_REPEAT,260GL_MIRRORED_REPEAT,261};262glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,263wrapParameters[stateUpdateCount % ArraySize(wrapParameters)]);264glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,265wrapParameters[stateUpdateCount % ArraySize(wrapParameters)]);266}267}268269glDrawArrays(GL_TRIANGLES, 0, 3);270}271272ASSERT_GL_NO_ERROR();273}274275TexturesParams D3D11Params(bool webglCompat, bool frequentUpdate)276{277TexturesParams params;278params.eglParameters = egl_platform::D3D11_NULL();279params.webgl = webglCompat;280if (frequentUpdate)281{282params.textureRebindFrequency = 1;283params.textureStateUpdateFrequency = 1;284}285return params;286}287288TexturesParams OpenGLOrGLESParams(bool webglCompat, bool frequentUpdate)289{290TexturesParams params;291params.eglParameters = egl_platform::OPENGL_OR_GLES_NULL();292params.webgl = webglCompat;293if (frequentUpdate)294{295params.textureRebindFrequency = 1;296params.textureStateUpdateFrequency = 1;297}298return params;299}300301TexturesParams VulkanParams(bool webglCompat, bool frequentUpdate)302{303TexturesParams params;304params.eglParameters = egl_platform::VULKAN_NULL();305params.webgl = webglCompat;306if (frequentUpdate)307{308params.textureRebindFrequency = 1;309params.textureStateUpdateFrequency = 1;310}311return params;312}313314TEST_P(TexturesBenchmark, Run)315{316run();317}318319ANGLE_INSTANTIATE_TEST(TexturesBenchmark,320D3D11Params(false, false),321D3D11Params(true, false),322D3D11Params(false, true),323D3D11Params(true, true),324OpenGLOrGLESParams(false, false),325OpenGLOrGLESParams(true, false),326OpenGLOrGLESParams(false, true),327OpenGLOrGLESParams(true, true),328VulkanParams(false, false),329VulkanParams(true, false),330VulkanParams(false, true),331VulkanParams(true, true));332} // namespace angle333334335