Home | History | Annotate | Download | only in glshared
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL (ES) 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 Single-program test case wrapper for ShaderPerformanceMeasurer.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "glsShaderPerformanceCase.hpp"
     25 #include "tcuRenderTarget.hpp"
     26 #include "deStringUtil.hpp"
     27 #include "deMath.h"
     28 
     29 #include "glwFunctions.hpp"
     30 #include "glwEnums.hpp"
     31 
     32 using tcu::Vec4;
     33 using tcu::TestLog;
     34 using namespace glw; // GL types
     35 
     36 namespace deqp
     37 {
     38 namespace gls
     39 {
     40 
     41 ShaderPerformanceCase::ShaderPerformanceCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, PerfCaseType caseType)
     42 	: tcu::TestCase		(testCtx, tcu::NODETYPE_PERFORMANCE, name, description)
     43 	, m_renderCtx		(renderCtx)
     44 	, m_caseType		(caseType)
     45 	, m_program			(DE_NULL)
     46 	, m_measurer		(renderCtx, caseType)
     47 {
     48 }
     49 
     50 ShaderPerformanceCase::~ShaderPerformanceCase (void)
     51 {
     52 	ShaderPerformanceCase::deinit();
     53 }
     54 
     55 void ShaderPerformanceCase::setGridSize (int gridW, int gridH)
     56 {
     57 	m_measurer.setGridSize(gridW, gridH);
     58 }
     59 
     60 void ShaderPerformanceCase::setViewportSize (int width, int height)
     61 {
     62 	m_measurer.setViewportSize(width, height);
     63 }
     64 
     65 void ShaderPerformanceCase::setVertexFragmentRatio (float fragmentsPerVertices)
     66 {
     67 	const float	eps			= 0.01f;
     68 	int			gridW		= 255;
     69 	int			gridH		= 255;
     70 	int			viewportW	= m_renderCtx.getRenderTarget().getWidth();
     71 	int			viewportH	= m_renderCtx.getRenderTarget().getHeight();
     72 
     73 	for (int i = 0; i < 10; i++)
     74 	{
     75 		int		numVert	= (gridW+1)*(gridH+1);
     76 		int		numFrag	= viewportW*viewportH;
     77 		float	ratio	= (float)numFrag / (float)numVert;
     78 
     79 		if (de::abs(ratio - fragmentsPerVertices) < eps)
     80 			break;
     81 		else if (ratio < fragmentsPerVertices)
     82 		{
     83 			// Not enough fragments.
     84 			numVert = deRoundFloatToInt32((float)numFrag / fragmentsPerVertices);
     85 
     86 			while ((gridW+1)*(gridH+1) > numVert)
     87 			{
     88 				if (gridW > gridH)
     89 					gridW -= 1;
     90 				else
     91 					gridH -= 1;
     92 			}
     93 		}
     94 		else
     95 		{
     96 			// Not enough vertices.
     97 			numFrag = deRoundFloatToInt32((float)numVert * fragmentsPerVertices);
     98 
     99 			while (viewportW*viewportH > numFrag)
    100 			{
    101 				if (viewportW > viewportH)
    102 					viewportW -= 1;
    103 				else
    104 					viewportH -= 1;
    105 			}
    106 		}
    107 	}
    108 
    109 	float finalRatio = (float)(viewportW*viewportH) / (float)((gridW+1)*(gridH+1));
    110 	m_testCtx.getLog() << TestLog::Message << "Requested fragment/vertex-ratio: " << de::floatToString(fragmentsPerVertices, 2) << "\n"
    111 										   << "Computed fragment/vertex-ratio: " << de::floatToString(finalRatio, 2)
    112 					   << TestLog::EndMessage;
    113 
    114 	setGridSize(gridW, gridH);
    115 	setViewportSize(viewportW, viewportH);
    116 }
    117 
    118 static void logRenderTargetInfo (TestLog& log, const tcu::RenderTarget& renderTarget)
    119 {
    120 	log << TestLog::Section("RenderTarget", "Render target")
    121 		<< TestLog::Message << "size: " << renderTarget.getWidth() << "x" << renderTarget.getHeight() << TestLog::EndMessage
    122 		<< TestLog::Message << "bits:"
    123 							<< " R" << renderTarget.getPixelFormat().redBits
    124 							<< " G" << renderTarget.getPixelFormat().greenBits
    125 							<< " B" << renderTarget.getPixelFormat().blueBits
    126 							<< " A" << renderTarget.getPixelFormat().alphaBits
    127 							<< " D" << renderTarget.getDepthBits()
    128 							<< " S" << renderTarget.getStencilBits()
    129 							<< TestLog::EndMessage;
    130 
    131 	if (renderTarget.getNumSamples() != 0)
    132 		log << TestLog::Message << renderTarget.getNumSamples() << "x MSAA" << TestLog::EndMessage;
    133 	else
    134 		log << TestLog::Message << "No MSAA" << TestLog::EndMessage;
    135 
    136 	log << TestLog::EndSection;
    137 }
    138 
    139 void ShaderPerformanceCase::init (void)
    140 {
    141 	tcu::TestLog& log = m_testCtx.getLog();
    142 
    143 	m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(m_vertShaderSource, m_fragShaderSource));
    144 
    145 	if (m_program->isOk())
    146 	{
    147 		const int initialCallCount = m_initialCalibration ? m_initialCalibration->initialNumCalls : 1;
    148 		logRenderTargetInfo(log, m_renderCtx.getRenderTarget());
    149 		m_measurer.init(m_program->getProgram(), m_attributes, initialCallCount);
    150 		m_measurer.logParameters(log);
    151 		log << *m_program;
    152 	}
    153 	else
    154 	{
    155 		log << *m_program;
    156 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
    157 		return; // Skip rest of init.
    158 	}
    159 
    160 	setupProgram(m_program->getProgram());
    161 	setupRenderState();
    162 }
    163 
    164 void ShaderPerformanceCase::deinit (void)
    165 {
    166 	delete m_program;
    167 	m_program = DE_NULL;
    168 
    169 	m_measurer.deinit();
    170 }
    171 
    172 void ShaderPerformanceCase::setupProgram (deUint32 program)
    173 {
    174 	DE_UNREF(program);
    175 }
    176 
    177 void ShaderPerformanceCase::setupRenderState (void)
    178 {
    179 }
    180 
    181 ShaderPerformanceCase::IterateResult ShaderPerformanceCase::iterate (void)
    182 {
    183 	DE_ASSERT(m_program);
    184 
    185 	if (!m_program->isOk()) // This happens when compilation failed in init().
    186 		return STOP;
    187 
    188 	m_measurer.iterate();
    189 
    190 	if (m_measurer.isFinished())
    191 	{
    192 		m_measurer.logMeasurementInfo(m_testCtx.getLog());
    193 
    194 		if (m_initialCalibration)
    195 			m_initialCalibration->initialNumCalls = de::max(1, m_measurer.getFinalCallCount());
    196 
    197 		const ShaderPerformanceMeasurer::Result result = m_measurer.getResult();
    198 		reportResult(result.megaVertPerSec, result.megaFragPerSec);
    199 		return STOP;
    200 	}
    201 	else
    202 		return CONTINUE;
    203 }
    204 
    205 void ShaderPerformanceCase::reportResult (float mvertPerSecond, float mfragPerSecond)
    206 {
    207 	float result = 0.0f;
    208 	switch (m_caseType)
    209 	{
    210 		case CASETYPE_VERTEX:	result = mvertPerSecond;	break;
    211 		case CASETYPE_FRAGMENT:	result = mfragPerSecond;	break;
    212 		case CASETYPE_BALANCED:	result = mfragPerSecond;	break;
    213 		default:
    214 			DE_ASSERT(false);
    215 	}
    216 
    217 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
    218 }
    219 
    220 ShaderPerformanceCaseGroup::ShaderPerformanceCaseGroup (tcu::TestContext& testCtx, const char* name, const char* description)
    221 	: TestCaseGroup					(testCtx, name, description)
    222 	, m_initialCalibrationStorage	(new ShaderPerformanceCase::InitialCalibration)
    223 {
    224 }
    225 
    226 void ShaderPerformanceCaseGroup::addChild (ShaderPerformanceCase* perfCase)
    227 {
    228 	perfCase->setCalibrationInitialParamStorage(m_initialCalibrationStorage);
    229 	TestCaseGroup::addChild(perfCase);
    230 }
    231 
    232 } // gls
    233 } // deqp
    234