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