Path: blob/main_old/src/tests/perf_tests/TextureUploadPerf.cpp
1693 views
//1// Copyright 2019 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// TextureUploadBenchmark:6// Performance test for uploading texture data.7//89#include "ANGLEPerfTest.h"1011#include <iostream>12#include <random>13#include <sstream>1415#include "test_utils/gl_raii.h"16#include "util/shader_utils.h"1718using namespace angle;1920namespace21{22constexpr unsigned int kIterationsPerStep = 2;2324struct TextureUploadParams final : public RenderTestParams25{26TextureUploadParams()27{28iterationsPerStep = kIterationsPerStep;29trackGpuTime = true;3031baseSize = 1024;32subImageSize = 64;3334webgl = false;35}3637std::string story() const override;3839GLsizei baseSize;40GLsizei subImageSize;4142bool webgl;43};4445std::ostream &operator<<(std::ostream &os, const TextureUploadParams ¶ms)46{47os << params.backendAndStory().substr(1);48return os;49}5051std::string TextureUploadParams::story() const52{53std::stringstream strstr;5455strstr << RenderTestParams::story();5657if (webgl)58{59strstr << "_webgl";60}6162return strstr.str();63}6465class TextureUploadBenchmarkBase : public ANGLERenderTest,66public ::testing::WithParamInterface<TextureUploadParams>67{68public:69TextureUploadBenchmarkBase(const char *benchmarkName);7071void initializeBenchmark() override;72void destroyBenchmark() override;7374protected:75void initShaders();7677GLuint mProgram = 0;78GLint mPositionLoc = -1;79GLint mSamplerLoc = -1;80GLuint mTexture = 0;81std::vector<float> mTextureData;82};8384class TextureUploadSubImageBenchmark : public TextureUploadBenchmarkBase85{86public:87TextureUploadSubImageBenchmark() : TextureUploadBenchmarkBase("TexSubImage")88{89addExtensionPrerequisite("GL_EXT_texture_storage");9091// http://anglebug.com/631992if (IsLinux() && IsIntel() &&93GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)94{95mSkipTest = true;96}97}9899void initializeBenchmark() override100{101TextureUploadBenchmarkBase::initializeBenchmark();102103const auto ¶ms = GetParam();104glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.baseSize, params.baseSize);105}106107void drawBenchmark() override;108};109110class TextureUploadFullMipBenchmark : public TextureUploadBenchmarkBase111{112public:113TextureUploadFullMipBenchmark() : TextureUploadBenchmarkBase("TextureUpload") {}114115void drawBenchmark() override;116};117118class PBOSubImageBenchmark : public TextureUploadBenchmarkBase119{120public:121PBOSubImageBenchmark() : TextureUploadBenchmarkBase("PBO") {}122123void initializeBenchmark() override124{125TextureUploadBenchmarkBase::initializeBenchmark();126127const auto ¶ms = GetParam();128129glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.baseSize, params.baseSize);130131glGenBuffers(1, &mPBO);132glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);133glBufferData(GL_PIXEL_UNPACK_BUFFER, params.baseSize * params.baseSize * 4,134mTextureData.data(), GL_STREAM_DRAW);135}136137void destroyBenchmark()138{139TextureUploadBenchmarkBase::destroyBenchmark();140glDeleteBuffers(1, &mPBO);141}142143void drawBenchmark() override;144145private:146GLuint mPBO;147};148149class PBOCompressedSubImageBenchmark : public TextureUploadBenchmarkBase150{151public:152PBOCompressedSubImageBenchmark() : TextureUploadBenchmarkBase("PBOCompressed") {}153154void initializeBenchmark() override155{156TextureUploadBenchmarkBase::initializeBenchmark();157158const auto ¶ms = GetParam();159160glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, params.baseSize,161params.baseSize);162163glGenBuffers(1, &mPBO);164glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);165glBufferData(GL_PIXEL_UNPACK_BUFFER, params.subImageSize * params.subImageSize / 2,166mTextureData.data(), GL_STREAM_DRAW);167}168169void destroyBenchmark()170{171TextureUploadBenchmarkBase::destroyBenchmark();172glDeleteBuffers(1, &mPBO);173}174175void drawBenchmark() override;176177private:178GLuint mPBO;179};180181TextureUploadBenchmarkBase::TextureUploadBenchmarkBase(const char *benchmarkName)182: ANGLERenderTest(benchmarkName, GetParam())183{184setWebGLCompatibilityEnabled(GetParam().webgl);185setRobustResourceInit(GetParam().webgl);186187// Crashes on nvidia+d3d11. http://crbug.com/945415188if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)189{190mSkipTest = true;191}192}193194void TextureUploadBenchmarkBase::initializeBenchmark()195{196const auto ¶ms = GetParam();197198initShaders();199glClearColor(0.0f, 0.0f, 0.0f, 0.0f);200glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());201202if (mIsTimestampQueryAvailable && params.webgl)203{204glRequestExtensionANGLE("GL_EXT_disjoint_timer_query");205}206207glActiveTexture(GL_TEXTURE0);208glGenTextures(1, &mTexture);209glBindTexture(GL_TEXTURE_2D, mTexture);210211glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);212glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);213glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);214glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);215216ASSERT_TRUE(params.baseSize >= params.subImageSize);217mTextureData.resize(params.baseSize * params.baseSize * 4, 0.5);218219ASSERT_GL_NO_ERROR();220}221222void TextureUploadBenchmarkBase::initShaders()223{224constexpr char kVS[] = R"(attribute vec4 a_position;225void main()226{227gl_Position = a_position;228})";229230constexpr char kFS[] = R"(precision mediump float;231uniform sampler2D s_texture;232void main()233{234gl_FragColor = texture2D(s_texture, vec2(0, 0));235})";236237mProgram = CompileProgram(kVS, kFS);238ASSERT_NE(0u, mProgram);239240mPositionLoc = glGetAttribLocation(mProgram, "a_position");241mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");242glUseProgram(mProgram);243glUniform1i(mSamplerLoc, 0);244245glDisable(GL_DEPTH_TEST);246247ASSERT_GL_NO_ERROR();248}249250void TextureUploadBenchmarkBase::destroyBenchmark()251{252glDeleteTextures(1, &mTexture);253glDeleteProgram(mProgram);254}255256void TextureUploadSubImageBenchmark::drawBenchmark()257{258const auto ¶ms = GetParam();259260startGpuTimer();261for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)262{263glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.baseSize - params.subImageSize),264rand() % (params.baseSize - params.subImageSize), params.subImageSize,265params.subImageSize, GL_RGBA, GL_UNSIGNED_BYTE, mTextureData.data());266267// Perform a draw just so the texture data is flushed. With the position attributes not268// set, a constant default value is used, resulting in a very cheap draw.269glDrawArrays(GL_TRIANGLES, 0, 3);270}271stopGpuTimer();272273ASSERT_GL_NO_ERROR();274}275276void TextureUploadFullMipBenchmark::drawBenchmark()277{278const auto ¶ms = GetParam();279280startGpuTimer();281for (size_t it = 0; it < params.iterationsPerStep; ++it)282{283// Stage data for all mips284GLint mip = 0;285for (GLsizei levelSize = params.baseSize; levelSize > 0; levelSize >>= 1)286{287glTexImage2D(GL_TEXTURE_2D, mip++, GL_RGBA, levelSize, levelSize, 0, GL_RGBA,288GL_UNSIGNED_BYTE, mTextureData.data());289}290291// Perform a draw just so the texture data is flushed. With the position attributes not292// set, a constant default value is used, resulting in a very cheap draw.293glDrawArrays(GL_TRIANGLES, 0, 3);294}295stopGpuTimer();296297ASSERT_GL_NO_ERROR();298}299300void PBOSubImageBenchmark::drawBenchmark()301{302const auto ¶ms = GetParam();303304startGpuTimer();305for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)306{307glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.baseSize - params.subImageSize),308rand() % (params.baseSize - params.subImageSize), params.subImageSize,309params.subImageSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);310311// Perform a draw just so the texture data is flushed. With the position attributes not312// set, a constant default value is used, resulting in a very cheap draw.313glDrawArrays(GL_TRIANGLES, 0, 3);314}315stopGpuTimer();316317ASSERT_GL_NO_ERROR();318}319320void PBOCompressedSubImageBenchmark::drawBenchmark()321{322const auto ¶ms = GetParam();323324startGpuTimer();325for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)326{327glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, params.subImageSize, params.subImageSize,328GL_COMPRESSED_RGB8_ETC2,329params.subImageSize * params.subImageSize / 2, 0);330331// Perform a draw just so the texture data is flushed. With the position attributes not332// set, a constant default value is used, resulting in a very cheap draw.333glDrawArrays(GL_TRIANGLES, 0, 3);334}335stopGpuTimer();336337ASSERT_GL_NO_ERROR();338}339340TextureUploadParams D3D11Params(bool webglCompat)341{342TextureUploadParams params;343params.eglParameters = egl_platform::D3D11();344params.webgl = webglCompat;345return params;346}347348TextureUploadParams OpenGLOrGLESParams(bool webglCompat)349{350TextureUploadParams params;351params.eglParameters = egl_platform::OPENGL_OR_GLES();352params.webgl = webglCompat;353return params;354}355356TextureUploadParams VulkanParams(bool webglCompat)357{358TextureUploadParams params;359params.eglParameters = egl_platform::VULKAN();360params.webgl = webglCompat;361return params;362}363364TextureUploadParams VulkanPBOParams(GLsizei baseSize, GLsizei subImageSize)365{366TextureUploadParams params;367params.eglParameters = egl_platform::VULKAN();368params.webgl = false;369params.trackGpuTime = false;370params.baseSize = baseSize;371params.subImageSize = subImageSize;372return params;373}374375TextureUploadParams ES3OpenGLPBOParams(GLsizei baseSize, GLsizei subImageSize)376{377TextureUploadParams params;378params.eglParameters = egl_platform::OPENGL();379params.majorVersion = 3;380params.minorVersion = 0;381params.webgl = false;382params.trackGpuTime = false;383params.baseSize = baseSize;384params.subImageSize = subImageSize;385return params;386}387388} // anonymous namespace389390TEST_P(TextureUploadSubImageBenchmark, Run)391{392run();393}394395TEST_P(TextureUploadFullMipBenchmark, Run)396{397run();398}399400TEST_P(PBOSubImageBenchmark, Run)401{402run();403}404405TEST_P(PBOCompressedSubImageBenchmark, Run)406{407run();408}409410using namespace params;411412ANGLE_INSTANTIATE_TEST(TextureUploadSubImageBenchmark,413D3D11Params(false),414D3D11Params(true),415OpenGLOrGLESParams(false),416OpenGLOrGLESParams(true),417VulkanParams(false),418NullDevice(VulkanParams(false)),419VulkanParams(true));420421ANGLE_INSTANTIATE_TEST(TextureUploadFullMipBenchmark,422D3D11Params(false),423D3D11Params(true),424OpenGLOrGLESParams(false),425OpenGLOrGLESParams(true),426VulkanParams(false),427VulkanParams(true));428429GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PBOSubImageBenchmark);430ANGLE_INSTANTIATE_TEST(PBOSubImageBenchmark,431ES3OpenGLPBOParams(1024, 128),432VulkanPBOParams(1024, 128));433434GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PBOCompressedSubImageBenchmark);435ANGLE_INSTANTIATE_TEST(PBOCompressedSubImageBenchmark,436ES3OpenGLPBOParams(128, 128),437VulkanPBOParams(128, 128));438439440