1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.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 "es3pTextureCases.hpp" 25#include "glsShaderPerformanceCase.hpp" 26#include "tcuTextureUtil.hpp" 27#include "tcuRenderTarget.hpp" 28#include "gluTexture.hpp" 29#include "gluTextureUtil.hpp" 30#include "gluStrUtil.hpp" 31 32#include "deStringUtil.hpp" 33 34#include "glwEnums.hpp" 35#include "glwFunctions.hpp" 36 37namespace deqp 38{ 39namespace gles3 40{ 41namespace Performance 42{ 43 44using namespace gls; 45using namespace glw; // GL types 46using tcu::Vec2; 47using tcu::Vec3; 48using tcu::Vec4; 49using tcu::IVec4; 50using std::string; 51using std::vector; 52using tcu::TestLog; 53 54Texture2DRenderCase::Texture2DRenderCase (Context& context, 55 const char* name, 56 const char* description, 57 deUint32 internalFormat, 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_internalFormat (internalFormat) 67 , m_wrapS (wrapS) 68 , m_wrapT (wrapT) 69 , m_minFilter (minFilter) 70 , m_magFilter (magFilter) 71 , m_coordTransform (coordTransform) 72 , m_numTextures (numTextures) 73 , m_powerOfTwo (powerOfTwo) 74{ 75} 76 77Texture2DRenderCase::~Texture2DRenderCase (void) 78{ 79 for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) 80 delete *i; 81 m_textures.clear(); 82} 83 84static inline int roundDownToPowerOfTwo (int val) 85{ 86 DE_ASSERT(val >= 0); 87 int l0 = deClz32(val); 88 return val & ~((1<<(31-l0))-1); 89} 90 91void Texture2DRenderCase::init (void) 92{ 93 TestLog& log = m_testCtx.getLog(); 94 95 const tcu::TextureFormat texFormat = glu::mapGLInternalFormat(m_internalFormat); 96 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat); 97 const glu::Precision samplerPrec = (texFormat.type == tcu::TextureFormat::FLOAT || 98 texFormat.type == tcu::TextureFormat::UNSIGNED_INT32 || 99 texFormat.type == tcu::TextureFormat::SIGNED_INT32) 100 ? glu::PRECISION_HIGHP : glu::PRECISION_MEDIUMP; 101 const glu::DataType samplerType = glu::getSampler2DType(texFormat); 102 const bool isIntUint = samplerType == glu::TYPE_INT_SAMPLER_2D || samplerType == glu::TYPE_UINT_SAMPLER_2D; 103 104 int width = m_renderCtx.getRenderTarget().getWidth(); 105 int height = m_renderCtx.getRenderTarget().getHeight(); 106 107 if (m_powerOfTwo) 108 { 109 width = roundDownToPowerOfTwo(width); 110 height = roundDownToPowerOfTwo(height); 111 } 112 113 bool mipmaps = m_minFilter == GL_NEAREST_MIPMAP_NEAREST || 114 m_minFilter == GL_NEAREST_MIPMAP_LINEAR || 115 m_minFilter == GL_LINEAR_MIPMAP_NEAREST || 116 m_minFilter == GL_LINEAR_MIPMAP_LINEAR; 117 118 DE_ASSERT(m_powerOfTwo || (!mipmaps && m_wrapS == GL_CLAMP_TO_EDGE && m_wrapT == GL_CLAMP_TO_EDGE)); 119 120 Vec2 p00 = (m_coordTransform * Vec3(0.0f, 0.0f, 1.0f)).swizzle(0,1); 121 Vec2 p10 = (m_coordTransform * Vec3(1.0f, 0.0f, 1.0f)).swizzle(0,1); 122 Vec2 p01 = (m_coordTransform * Vec3(0.0f, 1.0f, 1.0f)).swizzle(0,1); 123 Vec2 p11 = (m_coordTransform * Vec3(1.0f, 1.0f, 1.0f)).swizzle(0,1); 124 125 m_attributes.push_back(AttribSpec("a_coords", Vec4(p00.x(), p00.y(), 0.0f, 0.0f), 126 Vec4(p10.x(), p10.y(), 0.0f, 0.0f), 127 Vec4(p01.x(), p01.y(), 0.0f, 0.0f), 128 Vec4(p11.x(), p11.y(), 0.0f, 0.0f))); 129 130 log << TestLog::Message << "Size: " << width << "x" << height << TestLog::EndMessage; 131 log << TestLog::Message << "Format: " <<glu::getTextureFormatName(m_internalFormat) << TestLog::EndMessage; 132 log << TestLog::Message << "Coords: " << p00 << ", " << p10 << ", " << p01 << ", " << p11 << TestLog::EndMessage; 133 log << TestLog::Message << "Wrap: " << glu::getTextureWrapModeStr(m_wrapS) << " / " << glu::getTextureWrapModeStr(m_wrapT) << TestLog::EndMessage; 134 log << TestLog::Message << "Filter: " << glu::getTextureFilterStr(m_minFilter) << " / " << glu::getTextureFilterStr(m_magFilter) << TestLog::EndMessage; 135 log << TestLog::Message << "Mipmaps: " << (mipmaps ? "true" : "false") << TestLog::EndMessage; 136 log << TestLog::Message << "Using additive blending." << TestLog::EndMessage; 137 138 // Use same viewport size as texture size. 139 setViewportSize(width, height); 140 141 m_vertShaderSource = 142 "#version 300 es\n" 143 "in highp vec4 a_position;\n" 144 "in mediump vec2 a_coords;\n" 145 "out mediump vec2 v_coords;\n" 146 "void main (void)\n" 147 "{\n" 148 " gl_Position = a_position;\n" 149 " v_coords = a_coords;\n" 150 "}\n"; 151 152 std::ostringstream fragSrc; 153 fragSrc << "#version 300 es\n"; 154 fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; 155 fragSrc << "in mediump vec2 v_coords;\n"; 156 157 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 158 fragSrc << "uniform " << glu::getPrecisionName(samplerPrec) << " " << glu::getDataTypeName(samplerType) << " u_sampler" << texNdx << ";\n"; 159 160 fragSrc << "void main (void)\n" 161 << "{\n"; 162 163 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 164 { 165 if (texNdx == 0) 166 fragSrc << "\t" << glu::getPrecisionName(samplerPrec) << " vec4 r = "; 167 else 168 fragSrc << "\tr += "; 169 170 if (isIntUint) 171 fragSrc << "vec4("; 172 173 fragSrc << "texture(u_sampler" << texNdx << ", v_coords)"; 174 175 if (isIntUint) 176 fragSrc << ")"; 177 178 fragSrc << ";\n"; 179 } 180 181 fragSrc << " o_color = r;\n" 182 << "}\n"; 183 184 m_fragShaderSource = fragSrc.str(); 185 186 m_textures.reserve(m_numTextures); 187 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 188 { 189 static const IVec4 swizzles[] = { IVec4(0,1,2,3), IVec4(1,2,3,0), IVec4(2,3,0,1), IVec4(3,0,1,2), 190 IVec4(3,2,1,0), IVec4(2,1,0,3), IVec4(1,0,3,2), IVec4(0,3,2,1) }; 191 const IVec4& sw = swizzles[texNdx % DE_LENGTH_OF_ARRAY(swizzles)]; 192 193 glu::Texture2D* texture = new glu::Texture2D(m_renderCtx, m_internalFormat, width, height); 194 m_textures.push_back(texture); 195 196 // Fill levels. 197 int numLevels = mipmaps ? texture->getRefTexture().getNumLevels() : 1; 198 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 199 { 200 // \todo [2013-06-02 pyry] Values are not scaled back to 0..1 range in shaders. 201 texture->getRefTexture().allocLevel(levelNdx); 202 tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(levelNdx), 203 fmtInfo.valueMin.swizzle(sw[0], sw[1], sw[2], sw[3]), 204 fmtInfo.valueMax.swizzle(sw[0], sw[1], sw[2], sw[3])); 205 } 206 207 texture->upload(); 208 } 209 210 ShaderPerformanceCase::init(); 211} 212 213void Texture2DRenderCase::deinit (void) 214{ 215 for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) 216 delete *i; 217 m_textures.clear(); 218 219 ShaderPerformanceCase::deinit(); 220} 221 222void Texture2DRenderCase::setupProgram (deUint32 program) 223{ 224 const glw::Functions& gl = m_renderCtx.getFunctions(); 225 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 226 { 227 int samplerLoc = gl.getUniformLocation(program, (string("u_sampler") + de::toString(texNdx)).c_str()); 228 gl.uniform1i(samplerLoc, texNdx); 229 } 230} 231 232void Texture2DRenderCase::setupRenderState (void) 233{ 234 const glw::Functions& gl = m_renderCtx.getFunctions(); 235 236 // Setup additive blending. 237 gl.enable(GL_BLEND); 238 gl.blendFunc(GL_ONE, GL_ONE); 239 gl.blendEquation(GL_FUNC_ADD); 240 241 // Setup textures. 242 for (int texNdx = 0; texNdx < m_numTextures; texNdx++) 243 { 244 gl.activeTexture(GL_TEXTURE0 + texNdx); 245 gl.bindTexture(GL_TEXTURE_2D, m_textures[texNdx]->getGLTexture()); 246 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); 247 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter); 248 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS); 249 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT); 250 } 251} 252 253 254} // Performance 255} // gles3 256} // deqp 257