Home | History | Annotate | Download | only in performance
      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 
     37 namespace deqp
     38 {
     39 namespace gles3
     40 {
     41 namespace Performance
     42 {
     43 
     44 using namespace gls;
     45 using namespace glw; // GL types
     46 using tcu::Vec2;
     47 using tcu::Vec3;
     48 using tcu::Vec4;
     49 using tcu::IVec4;
     50 using std::string;
     51 using std::vector;
     52 using tcu::TestLog;
     53 
     54 Texture2DRenderCase::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 
     77 Texture2DRenderCase::~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 
     84 static 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 
     91 void 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 
    213 void 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 
    222 void 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 
    232 void 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