• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
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  glcAggressiveShaderOptimizationsTests.cpp
21  * \brief Conformance tests that checks if shader optimizations are not
22  *		  overly aggressive. This is done by compering result of complex
23  *		  trigonometric functions aproximation to shader buil
24  */ /*-------------------------------------------------------------------*/
25 
26 #include "glcAggressiveShaderOptimizationsTests.hpp"
27 #include "deSharedPtr.hpp"
28 #include "glsShaderExecUtil.hpp"
29 #include "gluContextInfo.hpp"
30 #include "gluDrawUtil.hpp"
31 #include "gluPixelTransfer.hpp"
32 #include "gluShaderProgram.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuImageCompare.hpp"
35 #include "tcuRenderTarget.hpp"
36 #include "tcuStringTemplate.hpp"
37 #include "tcuSurface.hpp"
38 #include "tcuTestLog.hpp"
39 
40 using namespace glw;
41 
42 namespace glcts
43 {
44 
45 enum ShaderType
46 {
47 	TEST_VERTEX_SHADER,
48 	TEST_FRAGMENT_SHADER
49 };
50 
51 struct TrigonometryCaseData
52 {
53 	const char* testedFunction;
54 	const char* testedType;
55 	const char* colorComponents;
56 	ShaderType  shaderType;
57 };
58 
59 class TrigonometryTestCase : public deqp::TestCase
60 {
61 public:
62 	TrigonometryTestCase(deqp::Context& context, const std::string& name, const TrigonometryCaseData& data);
63 	virtual ~TrigonometryTestCase();
64 
65 	IterateResult iterate(void);
66 
67 protected:
68 	glu::ProgramSources prepareSineSources(bool useBuiltin);
69 	glu::ProgramSources prepareCosineSources(bool useBuiltin);
70 
71 	void renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const;
72 
73 private:
74 	ShaderType  m_shaderType;
75 	const char* m_testedFunction;
76 	std::map<std::string, std::string> m_specializationMap;
77 };
78 
TrigonometryTestCase(deqp::Context & context,const std::string & name,const TrigonometryCaseData & data)79 TrigonometryTestCase::TrigonometryTestCase(deqp::Context& context, const std::string& name,
80 										   const TrigonometryCaseData& data)
81 	: deqp::TestCase(context, name.c_str(), ""), m_shaderType(data.shaderType), m_testedFunction(data.testedFunction)
82 {
83 	glu::ContextType contextType = m_context.getRenderContext().getType();
84 	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);
85 
86 	m_specializationMap["VERSION"]			= glu::getGLSLVersionDeclaration(glslVersion);
87 	m_specializationMap["TYPE"]				= data.testedType;
88 	m_specializationMap["COLOR_COMPONENTS"] = data.colorComponents;
89 
90 	if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
91 	{
92 		m_specializationMap["IN"]						= "in";
93 		m_specializationMap["OUT"]						= "out";
94 		m_specializationMap["ATTRIBUTE"]				= "in";
95 		m_specializationMap["FS_OUT_COLOR_NAME"]		= "fragColor";
96 		m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "out vec4 fragColor;";
97 	}
98 	else
99 	{
100 		m_specializationMap["IN"]						= "varying";
101 		m_specializationMap["OUT"]						= "varying";
102 		m_specializationMap["ATTRIBUTE"]				= "attribute";
103 		m_specializationMap["FS_OUT_COLOR_NAME"]		= "gl_FragColor";
104 		m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "";
105 	}
106 }
107 
~TrigonometryTestCase()108 TrigonometryTestCase::~TrigonometryTestCase()
109 {
110 }
111 
prepareSineSources(bool useBuiltinSin)112 glu::ProgramSources TrigonometryTestCase::prepareSineSources(bool useBuiltinSin)
113 {
114 	const char* vsDefault = "${VERSION}\n"
115 							"${ATTRIBUTE} highp vec2 position;\n"
116 							"${ATTRIBUTE} highp vec3 baseColor;\n"
117 							"${OUT} vec4 color;\n"
118 							"void main (void) {\n"
119 							"  color = vec4(baseColor, 1.0);\n"
120 							"  gl_Position = vec4(position, 0.0, 1.0);\n"
121 							"}\n";
122 
123 	const char* vsCalculateSin = "${VERSION}\n"
124 								 "${ATTRIBUTE} highp vec2 position;\n"
125 								 "${ATTRIBUTE} highp vec3 baseColor;\n"
126 								 "${OUT} vec4 color;\n"
127 								 "${SIN_FUNCTION_DEFINITION_VS}\n"
128 								 "void main (void) {\n"
129 								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
130 								 "  ${TYPE} c = baseColor.${COLOR_COMPONENTS} * M_2PI;\n"
131 								 "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c);\n"
132 								 "  \n"
133 								 "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
134 								 "  color.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
135 								 "  gl_Position = vec4(position, 0.0, 1.0);\n"
136 								 "}\n";
137 
138 	const char* fsDefault = "${VERSION}\n"
139 							"precision mediump float;\n"
140 							"${IN} vec4 color;\n"
141 							"${FS_OUT_COLOR_DECLARATION}\n"
142 							"void main (void) {\n"
143 							"  ${FS_OUT_COLOR_NAME} = color;\n"
144 							"}\n";
145 
146 	const char* fsCalculateSin = "${VERSION}\n"
147 								 "precision mediump float;\n"
148 								 "${IN} vec4 color;\n"
149 								 "${FS_OUT_COLOR_DECLARATION}\n\n"
150 								 "${SIN_FUNCTION_DEFINITION_FS}\n"
151 								 "void main (void) {\n"
152 								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
153 								 "  ${TYPE} c = color.${COLOR_COMPONENTS};\n"
154 								 "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c * M_2PI);\n"
155 								 "  \n"
156 								 "  ${FS_OUT_COLOR_NAME} =vec4(0.0, 0.0, 0.0, 1.0);\n"
157 								 "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
158 								 "}\n";
159 
160 	std::string vsTemplate;
161 	std::string fsTemplate;
162 
163 	if (m_shaderType == TEST_VERTEX_SHADER)
164 	{
165 		vsTemplate = vsCalculateSin;
166 		fsTemplate = fsDefault;
167 	}
168 	else
169 	{
170 		vsTemplate = vsDefault;
171 		fsTemplate = fsCalculateSin;
172 	}
173 
174 	if (useBuiltinSin)
175 	{
176 		m_specializationMap["SIN_FUNCTION_NAME"]		  = "sin";
177 		m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] = "";
178 		m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] = "";
179 	}
180 	else
181 	{
182 		std::string sinFunctionDefinitionVS = "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
183 											  "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
184 											  "  float sign = 1.0;\n"
185 											  "  float fact;\n"
186 											  "  float fact_of;\n"
187 											  "  \n"
188 											  "  // Taylors series expansion for sin \n"
189 											  "  for(int i = 0; i < 12; i++) {\n"
190 											  "    fact = 1.0;\n"
191 											  "    for(int j = 2; j <= 23; j++)\n"
192 											  "      if (j <= 2 * i + 1)\n"
193 											  "        fact *= float(j);\n"
194 											  "    \n"
195 											  "    sin_c += sign * pow(c, ${TYPE}(2.0 * float(i) + 1.0)) / fact;\n"
196 											  "    sign *= -1.0;\n"
197 											  "  }\n"
198 											  "  return sin_c;\n"
199 											  "}";
200 		std::string sinFunctionDefinitionFS = "float lerpHelper(float a, float b, float weight) {\n"
201 											  "  return a + (b - a) * weight;\n"
202 											  "}\n"
203 											  "float sinLerpHelper(int index, float weight) {\n"
204 											  "  float sArray[17];\n"
205 											  "  sArray[0] = 0.0;\n"
206 											  "  sArray[1] = 0.382683;\n"
207 											  "  sArray[2] = 0.707107;\n"
208 											  "  sArray[3] = 0.92388;\n"
209 											  "  sArray[4] = 1.0;\n"
210 											  "  sArray[5] = 0.92388;\n"
211 											  "  sArray[6] = 0.707107;\n"
212 											  "  sArray[7] = 0.382683;\n"
213 											  "  sArray[8] = 0.0;\n"
214 											  "  sArray[9] = -0.382683;\n"
215 											  "  sArray[10] = -0.707107;\n"
216 											  "  sArray[11] = -0.92388;\n"
217 											  "  sArray[12] = -1.0;\n"
218 											  "  sArray[13] = -0.923879;\n"
219 											  "  sArray[14] = -0.707107;\n"
220 											  "  sArray[15] = -0.382683;\n"
221 											  "  sArray[16] = 0.0;\n"
222 											  "  \n"
223 											  "  if (index == 0)\n"
224 											  "    return lerpHelper(sArray[0], sArray[1], weight);\n"
225 											  "  if (index == 1)\n"
226 											  "    return lerpHelper(sArray[1], sArray[2], weight);\n"
227 											  "  if (index == 2)\n"
228 											  "    return lerpHelper(sArray[2], sArray[3], weight);\n"
229 											  "  if (index == 3)\n"
230 											  "    return lerpHelper(sArray[3], sArray[4], weight);\n"
231 											  "  if (index == 4)\n"
232 											  "    return lerpHelper(sArray[4], sArray[5], weight);\n"
233 											  "  if (index == 5)\n"
234 											  "    return lerpHelper(sArray[5], sArray[6], weight);\n"
235 											  "  if (index == 6)\n"
236 											  "    return lerpHelper(sArray[6], sArray[7], weight);\n"
237 											  "  if (index == 7)\n"
238 											  "    return lerpHelper(sArray[7], sArray[8], weight);\n"
239 											  "  if (index == 8)\n"
240 											  "    return lerpHelper(sArray[8], sArray[9], weight);\n"
241 											  "  if (index == 9)\n"
242 											  "    return lerpHelper(sArray[9], sArray[10], weight);\n"
243 											  "  if (index == 10)\n"
244 											  "    return lerpHelper(sArray[10], sArray[11], weight);\n"
245 											  "  if (index == 11)\n"
246 											  "    return lerpHelper(sArray[11], sArray[12], weight);\n"
247 											  "  if (index == 12)\n"
248 											  "    return lerpHelper(sArray[12], sArray[13], weight);\n"
249 											  "  if (index == 13)\n"
250 											  "    return lerpHelper(sArray[13], sArray[14], weight);\n"
251 											  "  if (index == 14)\n"
252 											  "    return lerpHelper(sArray[14], sArray[15], weight);\n"
253 											  "  if (index == 15)\n"
254 											  "    return lerpHelper(sArray[15], sArray[16], weight);\n"
255 											  "  return sArray[16];\n"
256 											  "}\n"
257 											  "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
258 											  "  ${TYPE} arrVal = c * 2.546478971;\n"
259 											  "  ${TYPE} weight = arrVal - floor(arrVal);\n"
260 											  "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
261 											  "  ${INTERPOLATE_SIN}"
262 											  "  return sin_c;\n"
263 											  "}";
264 
265 		if (m_specializationMap["TYPE"] == "float")
266 		{
267 			m_specializationMap["INTERPOLATE_SIN"] = "\n"
268 													 "  int index = int(floor(arrVal));\n"
269 													 "  sin_c = sinLerpHelper(index, weight);\n";
270 		}
271 		else if (m_specializationMap["TYPE"] == "vec2")
272 		{
273 			m_specializationMap["INTERPOLATE_SIN"] = "\n"
274 													 "  int indexX = int(floor(arrVal.x));\n"
275 													 "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
276 													 "  int indexY = int(floor(arrVal.y));\n"
277 													 "  sin_c.y = sinLerpHelper(indexY, weight.y);\n";
278 		}
279 		else if (m_specializationMap["TYPE"] == "vec3")
280 		{
281 			m_specializationMap["INTERPOLATE_SIN"] = "\n"
282 													 "  int indexX = int(floor(arrVal.x));\n"
283 													 "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
284 													 "  int indexY = int(floor(arrVal.y));\n"
285 													 "  sin_c.y = sinLerpHelper(indexY, weight.y);\n"
286 													 "  int indexZ = int(floor(arrVal.z));\n"
287 													 "  sin_c.z = sinLerpHelper(indexZ, weight.z);\n";
288 		}
289 
290 		m_specializationMap["SIN_FUNCTION_NAME"] = "calculateSin";
291 		m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] =
292 			tcu::StringTemplate(sinFunctionDefinitionVS).specialize(m_specializationMap);
293 		m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] =
294 			tcu::StringTemplate(sinFunctionDefinitionFS).specialize(m_specializationMap);
295 	}
296 
297 	// Specialize shader templates
298 	vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
299 	fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
300 	return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
301 }
302 
prepareCosineSources(bool useBuiltinCos)303 glu::ProgramSources TrigonometryTestCase::prepareCosineSources(bool useBuiltinCos)
304 {
305 	const char* vsDefault = "${VERSION}\n"
306 							"${ATTRIBUTE} highp vec2 position;\n"
307 							"${ATTRIBUTE} highp vec3 baseColor;\n"
308 							"${OUT} vec4 color;\n"
309 							"void main (void) {\n"
310 							"  color = vec4(baseColor, 1.0);\n"
311 							"  gl_Position = vec4(position, 0.0, 1.0);\n"
312 							"}\n";
313 
314 	const char* vsCalculateCos = "${VERSION}\n"
315 								 "${ATTRIBUTE} highp vec2 position;\n"
316 								 "${ATTRIBUTE} highp vec3 baseColor;\n"
317 								 "${OUT} vec4 color;\n"
318 								 "${COS_FUNCTION_DEFINITION_VS}\n"
319 								 "void main (void) {\n"
320 								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
321 								 "  ${TYPE} c = baseColor.${COLOR_COMPONENTS};\n"
322 								 "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
323 								 "  \n"
324 								 "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
325 								 "  color.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
326 								 "  gl_Position = vec4(position, 0.0, 1.0);\n"
327 								 "}\n";
328 
329 	const char* fsDefault = "${VERSION}\n"
330 							"precision mediump float;\n"
331 							"${IN} vec4 color;\n"
332 							"${FS_OUT_COLOR_DECLARATION}\n"
333 							"void main (void) {\n"
334 							"  ${FS_OUT_COLOR_NAME} = color;\n"
335 							"}\n";
336 
337 	const char* fsCalculateCos = "${VERSION}\n"
338 								 "precision mediump float;\n"
339 								 "${IN} vec4 color;\n"
340 								 "${FS_OUT_COLOR_DECLARATION}\n\n"
341 								 "// function definitions \n"
342 								 "${COS_FUNCTION_DEFINITION_FS}\n"
343 								 "${TYPE} preprocessColor(${TYPE} c) {\n"
344 								 "  ${PREPROCESS_COLOR};\n"
345 								 "  return c;\n"
346 								 "}\n\n"
347 								 "void main (void) {\n"
348 								 "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
349 								 "  ${TYPE} c = preprocessColor(color.${COLOR_COMPONENTS});\n"
350 								 "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
351 								 "  \n"
352 								 "  ${FS_OUT_COLOR_NAME} = vec4(0.0, 0.0, 0.0, 1.0);\n"
353 								 "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
354 								 "}\n";
355 
356 	std::string vsTemplate;
357 	std::string fsTemplate;
358 
359 	if (m_shaderType == TEST_VERTEX_SHADER)
360 	{
361 		vsTemplate = vsCalculateCos;
362 		fsTemplate = fsDefault;
363 	}
364 	else
365 	{
366 		vsTemplate = vsDefault;
367 		fsTemplate = fsCalculateCos;
368 	}
369 
370 	if (useBuiltinCos)
371 	{
372 		m_specializationMap["PREPROCESS_COLOR"]			  = "";
373 		m_specializationMap["COS_FUNCTION_NAME"]		  = "cos";
374 		m_specializationMap["COS_FUNCTION_DEFINITION_VS"] = "";
375 		m_specializationMap["COS_FUNCTION_DEFINITION_FS"] = "";
376 	}
377 	else
378 	{
379 		std::string cosFunctionDefinitionVS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
380 											  "  ${TYPE} cos_c = ${TYPE}(1.0);\n"
381 											  "  float sign = -1.0;\n"
382 											  "  float fact =  1.0;\n"
383 											  "  \n"
384 											  "  for(int i = 2; i <= 20; i += 2) {\n"
385 											  "    fact  *= float(i)*float(i-1);\n"
386 											  "    cos_c += sign*pow(c, ${TYPE}(float(i)))/fact;\n"
387 											  "    sign = -sign;\n"
388 											  "  }\n"
389 											  "  return cos_c;\n"
390 											  "}";
391 		std::string cosFunctionDefinitionFS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
392 											  "  ${TYPE} cos_c = ${TYPE}(-1.0);\n"
393 											  "  float sign      = 1.0;\n"
394 											  "  float fact_even = 1.0;\n"
395 											  "  float fact_odd  = 1.0;\n"
396 											  "  ${TYPE} sum;\n"
397 											  "  ${TYPE} exp;\n"
398 											  "  \n"
399 											  "  for(int i = 2; i <= 10; i += 2) {\n"
400 											  "    fact_even *= float(i);\n"
401 											  "    fact_odd  *= float(i-1);\n"
402 											  "    exp = ${TYPE}(float(i/2));\n"
403 											  "    sum = sign * pow(abs(c), exp)/fact_even;\n"
404 											  "    cos_c += pow(abs(c), exp)*(sum/fact_odd);\n"
405 											  "    sign = -sign;\n"
406 											  "  }\n"
407 											  "  return cos_c;\n"
408 											  "}";
409 
410 		m_specializationMap["PREPROCESS_COLOR"]  = "c = (fract(abs(c)) - 0.5)";
411 		m_specializationMap["COS_FUNCTION_NAME"] = "calculateCos";
412 		m_specializationMap["COS_FUNCTION_DEFINITION_VS"] =
413 			tcu::StringTemplate(cosFunctionDefinitionVS).specialize(m_specializationMap);
414 		m_specializationMap["COS_FUNCTION_DEFINITION_FS"] =
415 			tcu::StringTemplate(cosFunctionDefinitionFS).specialize(m_specializationMap);
416 	}
417 
418 	// Specialize shader templates
419 	vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
420 	fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
421 	return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
422 }
423 
renderAndGrabSurface(glu::ProgramSources sources,tcu::Surface & result) const424 void TrigonometryTestCase::renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const
425 {
426 	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
427 	static const float	positions[]   = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };
428 	static const float	baseColors[]  = { 1.0, 0.0, 0.25, 0.75, 0.25, 1.0, 0.0, 1.0, 0.75, 0.25, 0.5, 0.0 };
429 
430 	glu::RenderContext&   renderContext = m_context.getRenderContext();
431 	const glw::Functions& gl			= renderContext.getFunctions();
432 	glu::ShaderProgram	testProgram(renderContext, sources);
433 	if (!testProgram.isOk())
434 	{
435 		m_testCtx.getLog() << testProgram;
436 		TCU_FAIL("Test program compilation failed");
437 	}
438 
439 	// Render
440 	gl.useProgram(testProgram.getProgram());
441 	const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, positions),
442 													 glu::va::Float("baseColor", 3, 4, 0, baseColors) };
443 	glu::draw(renderContext, testProgram.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
444 			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
445 
446 	// Grab surface
447 	glu::readPixels(renderContext, 0, 0, result.getAccess());
448 }
449 
iterate(void)450 tcu::TestNode::IterateResult TrigonometryTestCase::iterate(void)
451 {
452 	glu::RenderContext&   renderContext = m_context.getRenderContext();
453 	const glw::Functions& gl			= renderContext.getFunctions();
454 
455 	int  renderWidth  = 64;
456 	int  renderHeight = 64;
457 	if (renderWidth > m_context.getRenderTarget().getWidth())
458 		renderWidth = m_context.getRenderTarget().getWidth();
459 	if (renderHeight > m_context.getRenderTarget().getHeight())
460 		renderHeight = m_context.getRenderTarget().getHeight();
461 	bool isSin		  = std::string(m_testedFunction) == "sin";
462 
463 	gl.viewport(0, 0, renderWidth, renderHeight);
464 
465 	// Use program that will call trigonometric function aproximation
466 	tcu::Surface testSurface(renderWidth, renderHeight);
467 	if (isSin)
468 		renderAndGrabSurface(prepareSineSources(false), testSurface);
469 	else
470 		renderAndGrabSurface(prepareCosineSources(false), testSurface);
471 
472 	// Use reference program that will call builtin function
473 	tcu::Surface referenceSurface(renderWidth, renderHeight);
474 	if (isSin)
475 		renderAndGrabSurface(prepareSineSources(true), referenceSurface);
476 	else
477 		renderAndGrabSurface(prepareCosineSources(true), referenceSurface);
478 
479 	// Compare surfaces
480 	qpTestResult testResult = QP_TEST_RESULT_FAIL;
481 	if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, testSurface, 0.05f,
482 						  tcu::COMPARE_LOG_RESULT))
483 		testResult = QP_TEST_RESULT_PASS;
484 
485 	m_testCtx.setTestResult(testResult, qpGetTestResultName(testResult));
486 	return STOP;
487 }
488 
AggressiveShaderOptimizationsTests(deqp::Context & context)489 AggressiveShaderOptimizationsTests::AggressiveShaderOptimizationsTests(deqp::Context& context)
490 	: TestCaseGroup(context, "aggressive_optimizations", "checks if shader optimizations are not overly aggressive")
491 {
492 }
493 
~AggressiveShaderOptimizationsTests()494 AggressiveShaderOptimizationsTests::~AggressiveShaderOptimizationsTests()
495 {
496 }
497 
init(void)498 void AggressiveShaderOptimizationsTests::init(void)
499 {
500 	TrigonometryCaseData trigonometryCases[] = {
501 		{ "sin", "float", "r", TEST_VERTEX_SHADER },  { "sin", "float", "r", TEST_FRAGMENT_SHADER },
502 		{ "sin", "vec2", "rg", TEST_VERTEX_SHADER },  { "sin", "vec2", "rg", TEST_FRAGMENT_SHADER },
503 		{ "sin", "vec3", "rgb", TEST_VERTEX_SHADER }, { "sin", "vec3", "rgb", TEST_FRAGMENT_SHADER },
504 		{ "cos", "float", "r", TEST_VERTEX_SHADER },  { "cos", "float", "r", TEST_FRAGMENT_SHADER },
505 		{ "cos", "vec2", "rg", TEST_VERTEX_SHADER },  { "cos", "vec2", "rg", TEST_FRAGMENT_SHADER },
506 		{ "cos", "vec3", "rgb", TEST_VERTEX_SHADER }, { "cos", "vec3", "rgb", TEST_FRAGMENT_SHADER },
507 	};
508 
509 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(trigonometryCases); ++i)
510 	{
511 		const TrigonometryCaseData& tcd		   = trigonometryCases[i];
512 		std::string					shaderType = (tcd.shaderType == TEST_VERTEX_SHADER) ? "_vert" : "_frag";
513 		std::string					name	   = std::string(tcd.testedFunction) + "_" + tcd.testedType + shaderType;
514 		addChild(new TrigonometryTestCase(m_context, name, tcd));
515 	}
516 }
517 
518 } // glcts namespace
519