| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Texture format performance tests. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3pTextureCases.hpp" |
| #include "glsShaderPerformanceCase.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "gluTexture.hpp" |
| #include "gluTextureUtil.hpp" |
| #include "gluStrUtil.hpp" |
| |
| #include "deStringUtil.hpp" |
| |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Performance |
| { |
| |
| using namespace gls; |
| using namespace glw; // GL types |
| using tcu::Vec2; |
| using tcu::Vec3; |
| using tcu::Vec4; |
| using tcu::IVec4; |
| using std::string; |
| using std::vector; |
| using tcu::TestLog; |
| |
| Texture2DRenderCase::Texture2DRenderCase (Context& context, |
| const char* name, |
| const char* description, |
| deUint32 internalFormat, |
| deUint32 wrapS, |
| deUint32 wrapT, |
| deUint32 minFilter, |
| deUint32 magFilter, |
| const tcu::Mat3& coordTransform, |
| int numTextures, |
| bool powerOfTwo) |
| : ShaderPerformanceCase (context.getTestContext(), context.getRenderContext(), name, description, CASETYPE_FRAGMENT) |
| , m_internalFormat (internalFormat) |
| , m_wrapS (wrapS) |
| , m_wrapT (wrapT) |
| , m_minFilter (minFilter) |
| , m_magFilter (magFilter) |
| , m_coordTransform (coordTransform) |
| , m_numTextures (numTextures) |
| , m_powerOfTwo (powerOfTwo) |
| { |
| } |
| |
| Texture2DRenderCase::~Texture2DRenderCase (void) |
| { |
| for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) |
| delete *i; |
| m_textures.clear(); |
| } |
| |
| static inline int roundDownToPowerOfTwo (int val) |
| { |
| DE_ASSERT(val >= 0); |
| int l0 = deClz32(val); |
| return val & ~((1<<(31-l0))-1); |
| } |
| |
| void Texture2DRenderCase::init (void) |
| { |
| TestLog& log = m_testCtx.getLog(); |
| |
| const tcu::TextureFormat texFormat = glu::mapGLInternalFormat(m_internalFormat); |
| const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat); |
| const glu::Precision samplerPrec = (texFormat.type == tcu::TextureFormat::FLOAT || |
| texFormat.type == tcu::TextureFormat::UNSIGNED_INT32 || |
| texFormat.type == tcu::TextureFormat::SIGNED_INT32) |
| ? glu::PRECISION_HIGHP : glu::PRECISION_MEDIUMP; |
| const glu::DataType samplerType = glu::getSampler2DType(texFormat); |
| const bool isIntUint = samplerType == glu::TYPE_INT_SAMPLER_2D || samplerType == glu::TYPE_UINT_SAMPLER_2D; |
| |
| int width = m_renderCtx.getRenderTarget().getWidth(); |
| int height = m_renderCtx.getRenderTarget().getHeight(); |
| |
| if (m_powerOfTwo) |
| { |
| width = roundDownToPowerOfTwo(width); |
| height = roundDownToPowerOfTwo(height); |
| } |
| |
| bool mipmaps = m_minFilter == GL_NEAREST_MIPMAP_NEAREST || |
| m_minFilter == GL_NEAREST_MIPMAP_LINEAR || |
| m_minFilter == GL_LINEAR_MIPMAP_NEAREST || |
| m_minFilter == GL_LINEAR_MIPMAP_LINEAR; |
| |
| DE_ASSERT(m_powerOfTwo || (!mipmaps && m_wrapS == GL_CLAMP_TO_EDGE && m_wrapT == GL_CLAMP_TO_EDGE)); |
| |
| Vec2 p00 = (m_coordTransform * Vec3(0.0f, 0.0f, 1.0f)).swizzle(0,1); |
| Vec2 p10 = (m_coordTransform * Vec3(1.0f, 0.0f, 1.0f)).swizzle(0,1); |
| Vec2 p01 = (m_coordTransform * Vec3(0.0f, 1.0f, 1.0f)).swizzle(0,1); |
| Vec2 p11 = (m_coordTransform * Vec3(1.0f, 1.0f, 1.0f)).swizzle(0,1); |
| |
| m_attributes.push_back(AttribSpec("a_coords", Vec4(p00.x(), p00.y(), 0.0f, 0.0f), |
| Vec4(p10.x(), p10.y(), 0.0f, 0.0f), |
| Vec4(p01.x(), p01.y(), 0.0f, 0.0f), |
| Vec4(p11.x(), p11.y(), 0.0f, 0.0f))); |
| |
| log << TestLog::Message << "Size: " << width << "x" << height << TestLog::EndMessage; |
| log << TestLog::Message << "Format: " <<glu::getTextureFormatName(m_internalFormat) << TestLog::EndMessage; |
| log << TestLog::Message << "Coords: " << p00 << ", " << p10 << ", " << p01 << ", " << p11 << TestLog::EndMessage; |
| log << TestLog::Message << "Wrap: " << glu::getTextureWrapModeStr(m_wrapS) << " / " << glu::getTextureWrapModeStr(m_wrapT) << TestLog::EndMessage; |
| log << TestLog::Message << "Filter: " << glu::getTextureFilterStr(m_minFilter) << " / " << glu::getTextureFilterStr(m_magFilter) << TestLog::EndMessage; |
| log << TestLog::Message << "Mipmaps: " << (mipmaps ? "true" : "false") << TestLog::EndMessage; |
| log << TestLog::Message << "Using additive blending." << TestLog::EndMessage; |
| |
| // Use same viewport size as texture size. |
| setViewportSize(width, height); |
| |
| m_vertShaderSource = |
| "#version 300 es\n" |
| "in highp vec4 a_position;\n" |
| "in mediump vec2 a_coords;\n" |
| "out mediump vec2 v_coords;\n" |
| "void main (void)\n" |
| "{\n" |
| " gl_Position = a_position;\n" |
| " v_coords = a_coords;\n" |
| "}\n"; |
| |
| std::ostringstream fragSrc; |
| fragSrc << "#version 300 es\n"; |
| fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; |
| fragSrc << "in mediump vec2 v_coords;\n"; |
| |
| for (int texNdx = 0; texNdx < m_numTextures; texNdx++) |
| fragSrc << "uniform " << glu::getPrecisionName(samplerPrec) << " " << glu::getDataTypeName(samplerType) << " u_sampler" << texNdx << ";\n"; |
| |
| fragSrc << "void main (void)\n" |
| << "{\n"; |
| |
| for (int texNdx = 0; texNdx < m_numTextures; texNdx++) |
| { |
| if (texNdx == 0) |
| fragSrc << "\t" << glu::getPrecisionName(samplerPrec) << " vec4 r = "; |
| else |
| fragSrc << "\tr += "; |
| |
| if (isIntUint) |
| fragSrc << "vec4("; |
| |
| fragSrc << "texture(u_sampler" << texNdx << ", v_coords)"; |
| |
| if (isIntUint) |
| fragSrc << ")"; |
| |
| fragSrc << ";\n"; |
| } |
| |
| fragSrc << " o_color = r;\n" |
| << "}\n"; |
| |
| m_fragShaderSource = fragSrc.str(); |
| |
| m_textures.reserve(m_numTextures); |
| for (int texNdx = 0; texNdx < m_numTextures; texNdx++) |
| { |
| static const IVec4 swizzles[] = { IVec4(0,1,2,3), IVec4(1,2,3,0), IVec4(2,3,0,1), IVec4(3,0,1,2), |
| IVec4(3,2,1,0), IVec4(2,1,0,3), IVec4(1,0,3,2), IVec4(0,3,2,1) }; |
| const IVec4& sw = swizzles[texNdx % DE_LENGTH_OF_ARRAY(swizzles)]; |
| |
| glu::Texture2D* texture = new glu::Texture2D(m_renderCtx, m_internalFormat, width, height); |
| m_textures.push_back(texture); |
| |
| // Fill levels. |
| int numLevels = mipmaps ? texture->getRefTexture().getNumLevels() : 1; |
| for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) |
| { |
| // \todo [2013-06-02 pyry] Values are not scaled back to 0..1 range in shaders. |
| texture->getRefTexture().allocLevel(levelNdx); |
| tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(levelNdx), |
| fmtInfo.valueMin.swizzle(sw[0], sw[1], sw[2], sw[3]), |
| fmtInfo.valueMax.swizzle(sw[0], sw[1], sw[2], sw[3])); |
| } |
| |
| texture->upload(); |
| } |
| |
| ShaderPerformanceCase::init(); |
| } |
| |
| void Texture2DRenderCase::deinit (void) |
| { |
| for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++) |
| delete *i; |
| m_textures.clear(); |
| |
| ShaderPerformanceCase::deinit(); |
| } |
| |
| void Texture2DRenderCase::setupProgram (deUint32 program) |
| { |
| const glw::Functions& gl = m_renderCtx.getFunctions(); |
| for (int texNdx = 0; texNdx < m_numTextures; texNdx++) |
| { |
| int samplerLoc = gl.getUniformLocation(program, (string("u_sampler") + de::toString(texNdx)).c_str()); |
| gl.uniform1i(samplerLoc, texNdx); |
| } |
| } |
| |
| void Texture2DRenderCase::setupRenderState (void) |
| { |
| const glw::Functions& gl = m_renderCtx.getFunctions(); |
| |
| // Setup additive blending. |
| gl.enable(GL_BLEND); |
| gl.blendFunc(GL_ONE, GL_ONE); |
| gl.blendEquation(GL_FUNC_ADD); |
| |
| // Setup textures. |
| for (int texNdx = 0; texNdx < m_numTextures; texNdx++) |
| { |
| gl.activeTexture(GL_TEXTURE0 + texNdx); |
| gl.bindTexture(GL_TEXTURE_2D, m_textures[texNdx]->getGLTexture()); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT); |
| } |
| } |
| |
| |
| } // Performance |
| } // gles3 |
| } // deqp |