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 tcu::Vec2; 46 using tcu::Vec3; 47 using tcu::Vec4; 48 using tcu::IVec4; 49 using std::string; 50 using std::vector; 51 using tcu::TestLog; 52 53 Texture2DRenderCase::Texture2DRenderCase (Context& context, 54 const char* name, 55 const char* description, 56 deUint32 format, 57 deUint32 dataType, 58 deUint32 wrapS, 59 deUint32 wrapT, 60 deUint32 minFilter, 61 deUint32 magFilter, 62 const tcu::Mat3& coordTransform, 63 int numTextures, 64 bool powerOfTwo) 65 : ShaderPerformanceCase (context.getTestContext(), context.getRenderContext(), name, description, CASETYPE_FRAGMENT) 66 , m_format (format) 67 , m_dataType (dataType) 68 , m_wrapS (wrapS) 69 , m_wrapT (wrapT) 70 , m_minFilter (minFilter) 71 , m_magFilter (magFilter) 72 , m_coordTransform (coordTransform) 73 , m_numTextures (numTextures) 74 , m_powerOfTwo (powerOfTwo) 75 { 76 } 77 78 Texture2DRenderCase::~Texture2DRenderCase (void) 79 { 80 for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) 81 delete *i; 82 m_textures.clear(); 83 } 84 85 static inline int roundDownToPowerOfTwo (int val) 86 { 87 DE_ASSERT(val >= 0); 88 int l0 = deClz32(val); 89 return val & ~((1<<(31-l0))-1); 90 } 91 92 void Texture2DRenderCase::init (void) 93 { 94 TestLog& log = m_testCtx.getLog(); 95 96 int width = m_renderCtx.getRenderTarget().getWidth(); 97 int height = m_renderCtx.getRenderTarget().getHeight(); 98 99 if (m_powerOfTwo) 100 { 101 width = roundDownToPowerOfTwo(width); 102 height = roundDownToPowerOfTwo(height); 103 } 104 105 bool mipmaps = m_minFilter == GL_NEAREST_MIPMAP_NEAREST || 106 m_minFilter == GL_NEAREST_MIPMAP_LINEAR || 107 m_minFilter == GL_LINEAR_MIPMAP_NEAREST || 108 m_minFilter == GL_LINEAR_MIPMAP_LINEAR; 109 110 DE_ASSERT(m_powerOfTwo || (!mipmaps && m_wrapS == GL_CLAMP_TO_EDGE && m_wrapT == GL_CLAMP_TO_EDGE)); 111 112 Vec2 p00 = (m_coordTransform * Vec3(0.0f, 0.0f, 1.0f)).swizzle(0,1); 113 Vec2 p10 = (m_coordTransform * Vec3(1.0f, 0.0f, 1.0f)).swizzle(0,1); 114 Vec2 p01 = (m_coordTransform * Vec3(0.0f, 1.0f, 1.0f)).swizzle(0,1); 115 Vec2 p11 = (m_coordTransform * Vec3(1.0f, 1.0f, 1.0f)).swizzle(0,1); 116 117 m_attributes.push_back(AttribSpec("a_coords", Vec4(p00.x(), p00.y(), 0.0f, 0.0f), 118 Vec4(p10.x(), p10.y(), 0.0f, 0.0f), 119 Vec4(p01.x(), p01.y(), 0.0f, 0.0f), 120 Vec4(p11.x(), p11.y(), 0.0f, 0.0f))); 121 122 log << TestLog::Message << "Size: " << width << "x" << height << TestLog::EndMessage; 123 log << TestLog::Message << "Format: " <<glu::getTextureFormatName(m_format) << " " << glu::getTypeName(m_dataType) << TestLog::EndMessage; 124 log << TestLog::Message << "Coords: " << p00 << ", " << p10 << ", " << p01 << ", " << p11 << TestLog::EndMessage; 125 log << TestLog::Message << "Wrap: " << glu::getTextureWrapModeStr(m_wrapS) << " / " << glu::getTextureWrapModeStr(m_wrapT) << TestLog::EndMessage; 126 log << TestLog::Message << "Filter: " << glu::getTextureFilterStr(m_minFilter) << " / " << glu::getTextureFilterStr(m_magFilter) << TestLog::EndMessage; 127 log << TestLog::Message << "Mipmaps: " << (mipmaps ? "true" : "false") << TestLog::EndMessage; 128 log << TestLog::Message << "Using additive blending." << TestLog::EndMessage; 129 130 // Use same viewport size as texture size. 131 setViewportSize(width, height); 132 133 m_vertShaderSource = 134 "attribute highp vec4 a_position;\n" 135 "attribute mediump vec2 a_coords;\n" 136 "varying mediump vec2 v_coords;\n" 137 "void main (void)\n" 138 "{\n" 139 " gl_Position = a_position;\n" 140 " v_coords = a_coords;\n" 141 "}\n"; 142 143 std::ostringstream fragSrc; 144 fragSrc << "varying mediump vec2 v_coords;\n"; 145 146 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 147 fragSrc << "uniform sampler2D u_sampler" << texNdx << ";\n"; 148 149 fragSrc << "void main (void)\n" 150 << "{\n"; 151 152 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 153 fragSrc << "\t" << (texNdx == 0 ? "lowp vec4 r = " : "r += ") << "texture2D(u_sampler" << texNdx << ", v_coords);\n"; 154 155 fragSrc << " gl_FragColor = r;\n" 156 << "}\n"; 157 158 m_fragShaderSource = fragSrc.str(); 159 160 m_textures.reserve(m_numTextures); 161 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 162 { 163 static const IVec4 swizzles[] = { IVec4(0,1,2,3), IVec4(1,2,3,0), IVec4(2,3,0,1), IVec4(3,0,1,2), 164 IVec4(3,2,1,0), IVec4(2,1,0,3), IVec4(1,0,3,2), IVec4(0,3,2,1) }; 165 const IVec4& sw = swizzles[texNdx % DE_LENGTH_OF_ARRAY(swizzles)]; 166 167 glu::Texture2D* texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, width, height); 168 m_textures.push_back(texture); 169 170 // Fill levels. 171 int numLevels = mipmaps ? texture->getRefTexture().getNumLevels() : 1; 172 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 173 { 174 texture->getRefTexture().allocLevel(levelNdx); 175 tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(levelNdx), 176 Vec4(0.0f, 0.0f, 0.0f, 0.0f).swizzle(sw[0], sw[1], sw[2], sw[3]), 177 Vec4(1.0f, 1.0f, 1.0f, 1.0f).swizzle(sw[0], sw[1], sw[2], sw[3])); 178 } 179 180 texture->upload(); 181 } 182 183 ShaderPerformanceCase::init(); 184 } 185 186 void Texture2DRenderCase::deinit (void) 187 { 188 for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) 189 delete *i; 190 m_textures.clear(); 191 192 ShaderPerformanceCase::deinit(); 193 } 194 195 void Texture2DRenderCase::setupProgram (deUint32 program) 196 { 197 const glw::Functions& gl = m_renderCtx.getFunctions(); 198 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 199 { 200 int samplerLoc = gl.getUniformLocation(program, (string("u_sampler") + de::toString(texNdx)).c_str()); 201 gl.uniform1i(samplerLoc, texNdx); 202 } 203 } 204 205 void Texture2DRenderCase::setupRenderState (void) 206 { 207 const glw::Functions& gl = m_renderCtx.getFunctions(); 208 209 // Setup additive blending. 210 gl.enable(GL_BLEND); 211 gl.blendFunc(GL_ONE, GL_ONE); 212 gl.blendEquation(GL_FUNC_ADD); 213 214 // Setup textures. 215 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 216 { 217 gl.activeTexture(GL_TEXTURE0 + texNdx); 218 gl.bindTexture(GL_TEXTURE_2D, m_textures[texNdx]->getGLTexture()); 219 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); 220 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter); 221 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS); 222 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT); 223 } 224 } 225 226 227 } // Performance 228 } // gles2 229 } // deqp 230