xref: /aosp_15_r20/external/deqp/modules/gles2/performance/es2pTextureCases.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture format performance tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es2pTextureCases.hpp"
25 #include "glsShaderPerformanceCase.hpp"
26 #include "tcuTextureUtil.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include "gluTexture.hpp"
29 #include "gluStrUtil.hpp"
30 
31 #include "deStringUtil.hpp"
32 
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 
36 namespace deqp
37 {
38 namespace gles2
39 {
40 namespace Performance
41 {
42 
43 using namespace gls;
44 using namespace glw; // GL types
45 using std::string;
46 using std::vector;
47 using tcu::IVec4;
48 using tcu::TestLog;
49 using tcu::Vec2;
50 using tcu::Vec3;
51 using tcu::Vec4;
52 
Texture2DRenderCase(Context & context,const char * name,const char * description,uint32_t format,uint32_t dataType,uint32_t wrapS,uint32_t wrapT,uint32_t minFilter,uint32_t magFilter,const tcu::Mat3 & coordTransform,int numTextures,bool powerOfTwo)53 Texture2DRenderCase::Texture2DRenderCase(Context &context, const char *name, const char *description, uint32_t format,
54                                          uint32_t dataType, uint32_t wrapS, uint32_t wrapT, uint32_t minFilter,
55                                          uint32_t magFilter, const tcu::Mat3 &coordTransform, int numTextures,
56                                          bool powerOfTwo)
57     : ShaderPerformanceCase(context.getTestContext(), context.getRenderContext(), name, description, CASETYPE_FRAGMENT)
58     , m_format(format)
59     , m_dataType(dataType)
60     , m_wrapS(wrapS)
61     , m_wrapT(wrapT)
62     , m_minFilter(minFilter)
63     , m_magFilter(magFilter)
64     , m_coordTransform(coordTransform)
65     , m_numTextures(numTextures)
66     , m_powerOfTwo(powerOfTwo)
67 {
68 }
69 
~Texture2DRenderCase(void)70 Texture2DRenderCase::~Texture2DRenderCase(void)
71 {
72     for (vector<glu::Texture2D *>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
73         delete *i;
74     m_textures.clear();
75 }
76 
roundDownToPowerOfTwo(int val)77 static inline int roundDownToPowerOfTwo(int val)
78 {
79     DE_ASSERT(val >= 0);
80     int l0 = deClz32(val);
81     return val & ~((1 << (31 - l0)) - 1);
82 }
83 
init(void)84 void Texture2DRenderCase::init(void)
85 {
86     TestLog &log = m_testCtx.getLog();
87 
88     int width  = m_renderCtx.getRenderTarget().getWidth();
89     int height = m_renderCtx.getRenderTarget().getHeight();
90 
91     if (m_powerOfTwo)
92     {
93         width  = roundDownToPowerOfTwo(width);
94         height = roundDownToPowerOfTwo(height);
95     }
96 
97     bool mipmaps = m_minFilter == GL_NEAREST_MIPMAP_NEAREST || m_minFilter == GL_NEAREST_MIPMAP_LINEAR ||
98                    m_minFilter == GL_LINEAR_MIPMAP_NEAREST || m_minFilter == GL_LINEAR_MIPMAP_LINEAR;
99 
100     DE_ASSERT(m_powerOfTwo || (!mipmaps && m_wrapS == GL_CLAMP_TO_EDGE && m_wrapT == GL_CLAMP_TO_EDGE));
101 
102     Vec2 p00 = (m_coordTransform * Vec3(0.0f, 0.0f, 1.0f)).swizzle(0, 1);
103     Vec2 p10 = (m_coordTransform * Vec3(1.0f, 0.0f, 1.0f)).swizzle(0, 1);
104     Vec2 p01 = (m_coordTransform * Vec3(0.0f, 1.0f, 1.0f)).swizzle(0, 1);
105     Vec2 p11 = (m_coordTransform * Vec3(1.0f, 1.0f, 1.0f)).swizzle(0, 1);
106 
107     m_attributes.push_back(AttribSpec("a_coords", Vec4(p00.x(), p00.y(), 0.0f, 0.0f),
108                                       Vec4(p10.x(), p10.y(), 0.0f, 0.0f), Vec4(p01.x(), p01.y(), 0.0f, 0.0f),
109                                       Vec4(p11.x(), p11.y(), 0.0f, 0.0f)));
110 
111     log << TestLog::Message << "Size: " << width << "x" << height << TestLog::EndMessage;
112     log << TestLog::Message << "Format: " << glu::getTextureFormatName(m_format) << " " << glu::getTypeName(m_dataType)
113         << TestLog::EndMessage;
114     log << TestLog::Message << "Coords: " << p00 << ", " << p10 << ", " << p01 << ", " << p11 << TestLog::EndMessage;
115     log << TestLog::Message << "Wrap: " << glu::getTextureWrapModeStr(m_wrapS) << " / "
116         << glu::getTextureWrapModeStr(m_wrapT) << TestLog::EndMessage;
117     log << TestLog::Message << "Filter: " << glu::getTextureFilterStr(m_minFilter) << " / "
118         << glu::getTextureFilterStr(m_magFilter) << TestLog::EndMessage;
119     log << TestLog::Message << "Mipmaps: " << (mipmaps ? "true" : "false") << TestLog::EndMessage;
120     log << TestLog::Message << "Using additive blending." << TestLog::EndMessage;
121 
122     // Use same viewport size as texture size.
123     setViewportSize(width, height);
124 
125     m_vertShaderSource = "attribute highp vec4 a_position;\n"
126                          "attribute mediump vec2 a_coords;\n"
127                          "varying mediump vec2 v_coords;\n"
128                          "void main (void)\n"
129                          "{\n"
130                          "    gl_Position = a_position;\n"
131                          "    v_coords = a_coords;\n"
132                          "}\n";
133 
134     std::ostringstream fragSrc;
135     fragSrc << "varying mediump vec2 v_coords;\n";
136 
137     for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
138         fragSrc << "uniform sampler2D u_sampler" << texNdx << ";\n";
139 
140     fragSrc << "void main (void)\n"
141             << "{\n";
142 
143     for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
144         fragSrc << "\t" << (texNdx == 0 ? "lowp vec4 r = " : "r += ") << "texture2D(u_sampler" << texNdx
145                 << ", v_coords);\n";
146 
147     fragSrc << "    gl_FragColor = r;\n"
148             << "}\n";
149 
150     m_fragShaderSource = fragSrc.str();
151 
152     m_textures.reserve(m_numTextures);
153     for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
154     {
155         static const IVec4 swizzles[] = {IVec4(0, 1, 2, 3), IVec4(1, 2, 3, 0), IVec4(2, 3, 0, 1), IVec4(3, 0, 1, 2),
156                                          IVec4(3, 2, 1, 0), IVec4(2, 1, 0, 3), IVec4(1, 0, 3, 2), IVec4(0, 3, 2, 1)};
157         const IVec4 &sw               = swizzles[texNdx % DE_LENGTH_OF_ARRAY(swizzles)];
158 
159         glu::Texture2D *texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, width, height);
160         m_textures.push_back(texture);
161 
162         // Fill levels.
163         int numLevels = mipmaps ? texture->getRefTexture().getNumLevels() : 1;
164         for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
165         {
166             texture->getRefTexture().allocLevel(levelNdx);
167             tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(levelNdx),
168                                             Vec4(0.0f, 0.0f, 0.0f, 0.0f).swizzle(sw[0], sw[1], sw[2], sw[3]),
169                                             Vec4(1.0f, 1.0f, 1.0f, 1.0f).swizzle(sw[0], sw[1], sw[2], sw[3]));
170         }
171 
172         texture->upload();
173     }
174 
175     ShaderPerformanceCase::init();
176 }
177 
deinit(void)178 void Texture2DRenderCase::deinit(void)
179 {
180     for (vector<glu::Texture2D *>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
181         delete *i;
182     m_textures.clear();
183 
184     ShaderPerformanceCase::deinit();
185 }
186 
setupProgram(uint32_t program)187 void Texture2DRenderCase::setupProgram(uint32_t program)
188 {
189     const glw::Functions &gl = m_renderCtx.getFunctions();
190     for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
191     {
192         int samplerLoc = gl.getUniformLocation(program, (string("u_sampler") + de::toString(texNdx)).c_str());
193         gl.uniform1i(samplerLoc, texNdx);
194     }
195 }
196 
setupRenderState(void)197 void Texture2DRenderCase::setupRenderState(void)
198 {
199     const glw::Functions &gl = m_renderCtx.getFunctions();
200 
201     // Setup additive blending.
202     gl.enable(GL_BLEND);
203     gl.blendFunc(GL_ONE, GL_ONE);
204     gl.blendEquation(GL_FUNC_ADD);
205 
206     // Setup textures.
207     for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
208     {
209         gl.activeTexture(GL_TEXTURE0 + texNdx);
210         gl.bindTexture(GL_TEXTURE_2D, m_textures[texNdx]->getGLTexture());
211         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
212         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter);
213         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
214         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
215     }
216 }
217 
218 } // namespace Performance
219 } // namespace gles2
220 } // namespace deqp
221