// // Copyright 2023 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. // // RGBImageAllocationBenchmark: // GL_RGB8 image allocation and loading using GL_UNSIGNED_BYTE. // #include "ANGLEPerfTest.h" #include #include #include #include "test_utils/gl_raii.h" #include "util/shader_utils.h" using namespace angle; namespace { struct RGBImageAllocationParams final : public RenderTestParams { RGBImageAllocationParams() { iterationsPerStep = 1; } std::string story() const override; // Used to indicate whether the tested source pointer should be 4-byte-aligned. bool aligned; size_t textureSize; }; std::ostream &operator<<(std::ostream &os, const RGBImageAllocationParams ¶ms) { return os << params.backendAndStory().substr(1); } std::string RGBImageAllocationParams::story() const { std::stringstream strstr; strstr << RenderTestParams::story() << "_size" << textureSize << (aligned ? "_4bytealigned_src" : "_non4bytealigned_src"); return strstr.str(); } struct RGBColor { RGBColor() : r(0), g(0), b(0) {} RGBColor(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {} uint8_t r; uint8_t g; uint8_t b; }; class RGBImageAllocationBenchmark : public ANGLERenderTest, public ::testing::WithParamInterface { public: RGBImageAllocationBenchmark(); void initializeBenchmark() override; void drawBenchmark() override; void destroyBenchmark() override; protected: std::vector mColors; GLuint mTexture; size_t mOffset; size_t mTextureSize; }; RGBImageAllocationBenchmark::RGBImageAllocationBenchmark() : ANGLERenderTest("RGBImageAllocation", GetParam()) { mOffset = (GetParam().aligned) ? 0 : 1; mTextureSize = GetParam().textureSize; } void RGBImageAllocationBenchmark::initializeBenchmark() { // Initialize texture. The size in this test should be set to a power of two for easier data // allocation and avoiding alignment issues. ASSERT(gl::isPow2(mTextureSize)); glGenTextures(1, &mTexture); glBindTexture(GL_TEXTURE_2D, mTexture); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, mTextureSize, mTextureSize); // Initialize color data. It is expected for the color data pointer to be 4-byte-aligned. If // necessary, an extra pixel is allocated in the beginning to test the non-aligned case. ASSERT(reinterpret_cast(mColors.data()) % 4 == 0); mColors.resize(mOffset + mTextureSize * mTextureSize); for (size_t i = 0; i < mTextureSize * mTextureSize; i++) { mColors[mOffset + i] = RGBColor(1, 2, 3); } } void RGBImageAllocationBenchmark::destroyBenchmark() { glDeleteTextures(1, &mTexture); } void RGBImageAllocationBenchmark::drawBenchmark() { // Copy the next color data. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mTextureSize, mTextureSize, GL_RGB, GL_UNSIGNED_BYTE, mColors.data() + mOffset); glFinish(); ASSERT_GL_NO_ERROR(); } RGBImageAllocationParams VulkanParams(bool aligned, size_t textureSize) { RGBImageAllocationParams params; params.eglParameters = egl_platform::VULKAN(); params.majorVersion = 3; params.minorVersion = 0; params.aligned = aligned; params.textureSize = textureSize; return params; } RGBImageAllocationParams OpenGLOrGLESParams(bool aligned, size_t textureSize) { RGBImageAllocationParams params; params.eglParameters = egl_platform::OPENGL_OR_GLES(); params.majorVersion = 3; params.minorVersion = 0; params.aligned = aligned; params.textureSize = textureSize; return params; } RGBImageAllocationParams MetalParams(bool aligned, size_t textureSize) { RGBImageAllocationParams params; params.eglParameters = egl_platform::METAL(); params.majorVersion = 3; params.minorVersion = 0; params.aligned = aligned; params.textureSize = textureSize; return params; } RGBImageAllocationParams D3D11Params(bool aligned, size_t textureSize) { RGBImageAllocationParams params; params.eglParameters = egl_platform::D3D11(); params.majorVersion = 3; params.minorVersion = 0; params.aligned = aligned; params.textureSize = textureSize; return params; } } // anonymous namespace // Runs the test to measure the performance of RGB8 image allocation and loading. TEST_P(RGBImageAllocationBenchmark, Run) { run(); } using namespace params; ANGLE_INSTANTIATE_TEST(RGBImageAllocationBenchmark, VulkanParams(true, 256), VulkanParams(true, 2048), VulkanParams(false, 2048), OpenGLOrGLESParams(true, 256), OpenGLOrGLESParams(true, 2048), OpenGLOrGLESParams(false, 2048), MetalParams(true, 256), MetalParams(true, 2048), MetalParams(false, 2048), D3D11Params(true, 256), D3D11Params(true, 2048), D3D11Params(false, 2048));