1 //
2 // Copyright 2023 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // RGBImageAllocationBenchmark:
7 // GL_RGB8 image allocation and loading using GL_UNSIGNED_BYTE.
8 //
9
10 #include "ANGLEPerfTest.h"
11
12 #include <iostream>
13 #include <random>
14 #include <sstream>
15
16 #include "test_utils/gl_raii.h"
17 #include "util/shader_utils.h"
18
19 using namespace angle;
20
21 namespace
22 {
23 struct RGBImageAllocationParams final : public RenderTestParams
24 {
RGBImageAllocationParams__anon7d937d990111::RGBImageAllocationParams25 RGBImageAllocationParams() { iterationsPerStep = 1; }
26
27 std::string story() const override;
28
29 // Used to indicate whether the tested source pointer should be 4-byte-aligned.
30 bool aligned;
31 size_t textureSize;
32 };
33
operator <<(std::ostream & os,const RGBImageAllocationParams & params)34 std::ostream &operator<<(std::ostream &os, const RGBImageAllocationParams ¶ms)
35 {
36 return os << params.backendAndStory().substr(1);
37 }
38
story() const39 std::string RGBImageAllocationParams::story() const
40 {
41 std::stringstream strstr;
42
43 strstr << RenderTestParams::story() << "_size" << textureSize
44 << (aligned ? "_4bytealigned_src" : "_non4bytealigned_src");
45
46 return strstr.str();
47 }
48
49 struct RGBColor
50 {
RGBColor__anon7d937d990111::RGBColor51 RGBColor() : r(0), g(0), b(0) {}
RGBColor__anon7d937d990111::RGBColor52 RGBColor(uint8_t r, uint8_t g, uint8_t b) : r(r), g(g), b(b) {}
53 uint8_t r;
54 uint8_t g;
55 uint8_t b;
56 };
57
58 class RGBImageAllocationBenchmark : public ANGLERenderTest,
59 public ::testing::WithParamInterface<RGBImageAllocationParams>
60 {
61 public:
62 RGBImageAllocationBenchmark();
63
64 void initializeBenchmark() override;
65 void drawBenchmark() override;
66 void destroyBenchmark() override;
67
68 protected:
69 std::vector<RGBColor> mColors;
70 GLuint mTexture;
71 size_t mOffset;
72 size_t mTextureSize;
73 };
74
RGBImageAllocationBenchmark()75 RGBImageAllocationBenchmark::RGBImageAllocationBenchmark()
76 : ANGLERenderTest("RGBImageAllocation", GetParam())
77 {
78 mOffset = (GetParam().aligned) ? 0 : 1;
79 mTextureSize = GetParam().textureSize;
80 }
81
initializeBenchmark()82 void RGBImageAllocationBenchmark::initializeBenchmark()
83 {
84 // Initialize texture. The size in this test should be set to a power of two for easier data
85 // allocation and avoiding alignment issues.
86 ASSERT(gl::isPow2(mTextureSize));
87 glGenTextures(1, &mTexture);
88 glBindTexture(GL_TEXTURE_2D, mTexture);
89 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, mTextureSize, mTextureSize);
90
91 // Initialize color data. It is expected for the color data pointer to be 4-byte-aligned. If
92 // necessary, an extra pixel is allocated in the beginning to test the non-aligned case.
93 ASSERT(reinterpret_cast<uintptr_t>(mColors.data()) % 4 == 0);
94 mColors.resize(mOffset + mTextureSize * mTextureSize);
95 for (size_t i = 0; i < mTextureSize * mTextureSize; i++)
96 {
97 mColors[mOffset + i] = RGBColor(1, 2, 3);
98 }
99 }
100
destroyBenchmark()101 void RGBImageAllocationBenchmark::destroyBenchmark()
102 {
103 glDeleteTextures(1, &mTexture);
104 }
105
drawBenchmark()106 void RGBImageAllocationBenchmark::drawBenchmark()
107 {
108 // Copy the next color data.
109 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mTextureSize, mTextureSize, GL_RGB, GL_UNSIGNED_BYTE,
110 mColors.data() + mOffset);
111 glFinish();
112 ASSERT_GL_NO_ERROR();
113 }
114
VulkanParams(bool aligned,size_t textureSize)115 RGBImageAllocationParams VulkanParams(bool aligned, size_t textureSize)
116 {
117 RGBImageAllocationParams params;
118 params.eglParameters = egl_platform::VULKAN();
119 params.majorVersion = 3;
120 params.minorVersion = 0;
121 params.aligned = aligned;
122 params.textureSize = textureSize;
123 return params;
124 }
125
OpenGLOrGLESParams(bool aligned,size_t textureSize)126 RGBImageAllocationParams OpenGLOrGLESParams(bool aligned, size_t textureSize)
127 {
128 RGBImageAllocationParams params;
129 params.eglParameters = egl_platform::OPENGL_OR_GLES();
130 params.majorVersion = 3;
131 params.minorVersion = 0;
132 params.aligned = aligned;
133 params.textureSize = textureSize;
134 return params;
135 }
136
MetalParams(bool aligned,size_t textureSize)137 RGBImageAllocationParams MetalParams(bool aligned, size_t textureSize)
138 {
139 RGBImageAllocationParams params;
140 params.eglParameters = egl_platform::METAL();
141 params.majorVersion = 3;
142 params.minorVersion = 0;
143 params.aligned = aligned;
144 params.textureSize = textureSize;
145 return params;
146 }
147
D3D11Params(bool aligned,size_t textureSize)148 RGBImageAllocationParams D3D11Params(bool aligned, size_t textureSize)
149 {
150 RGBImageAllocationParams params;
151 params.eglParameters = egl_platform::D3D11();
152 params.majorVersion = 3;
153 params.minorVersion = 0;
154 params.aligned = aligned;
155 params.textureSize = textureSize;
156 return params;
157 }
158
159 } // anonymous namespace
160
161 // Runs the test to measure the performance of RGB8 image allocation and loading.
TEST_P(RGBImageAllocationBenchmark,Run)162 TEST_P(RGBImageAllocationBenchmark, Run)
163 {
164 run();
165 }
166
167 using namespace params;
168
169 ANGLE_INSTANTIATE_TEST(RGBImageAllocationBenchmark,
170 VulkanParams(true, 256),
171 VulkanParams(true, 2048),
172 VulkanParams(false, 2048),
173 OpenGLOrGLESParams(true, 256),
174 OpenGLOrGLESParams(true, 2048),
175 OpenGLOrGLESParams(false, 2048),
176 MetalParams(true, 256),
177 MetalParams(true, 2048),
178 MetalParams(false, 2048),
179 D3D11Params(true, 256),
180 D3D11Params(true, 2048),
181 D3D11Params(false, 2048));
182