• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2022-2022 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 /*!
21  * \file  esextcFragmentShadingRateAttachmentTests.hpp
22  * \brief FragmentShadingRateEXT Attachment related tests
23  */ /*-------------------------------------------------------------------*/
24 
25 #include "esextcFragmentShadingRateAttachmentTests.hpp"
26 #include "deRandom.h"
27 #include "esextcFragmentShadingRateTests.hpp"
28 #include "gluContextInfo.hpp"
29 #include "gluDefs.hpp"
30 #include "gluShaderProgram.hpp"
31 #include "glwEnums.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuTestLog.hpp"
34 
35 #define TRIANGLE_COUNT 100
36 
37 namespace glcts
38 {
39 
40 ///  Constructor
41 ///
42 /// @param context     Test context
43 /// @param extParams   extension params
44 /// @param testcaseParam Test case params
45 /// @param name        Test case's name
46 /// @param description Test case's description
FragmentShadingRateAttachment(Context & context,const ExtParameters & extParams,const FragmentShadingRateAttachment::TestcaseParam & testcaseParam,const char * name,const char * description)47 FragmentShadingRateAttachment::FragmentShadingRateAttachment(
48 	Context& context, const ExtParameters& extParams, const FragmentShadingRateAttachment::TestcaseParam& testcaseParam,
49 	const char* name, const char* description)
50 	: TestCaseBase(context, extParams, name, description), m_tcParam(testcaseParam), m_program(nullptr)
51 {
52 }
53 
54 /// Initialize test
init(void)55 void FragmentShadingRateAttachment::init(void)
56 {
57 	TestCaseBase::init();
58 
59 	// Skip if required extensions are not supported.
60 	if (!m_is_fragment_shading_rate_supported)
61 	{
62 		throw tcu::NotSupportedError(FRAGMENT_SHADING_RATE_NOT_SUPPORTED, "", __FILE__, __LINE__);
63 	}
64 
65 	if (!m_is_fragment_shading_rate_attachment_supported)
66 	{
67 		if (m_tcParam.attachmentShadingRate)
68 		{
69 			throw tcu::NotSupportedError(FRAGMENT_SHADING_RATE_NOT_SUPPORTED, "", __FILE__, __LINE__);
70 		}
71 
72 		if (m_tcParam.multiShadingRate)
73 		{
74 			throw tcu::NotSupportedError(FRAGMENT_SHADING_RATE_NOT_SUPPORTED, "", __FILE__, __LINE__);
75 		}
76 	}
77 
78 	if (!m_is_multiview_ovr_supported)
79 	{
80 		throw tcu::NotSupportedError(MULTIVIEW_OVR_NOT_SUPPORTED, "", __FILE__, __LINE__);
81 	}
82 }
83 
84 /// Deinitializes all GLES objects created for the test.
deinit(void)85 void FragmentShadingRateAttachment::deinit(void)
86 {
87 	// Retrieve GLES entry points.
88 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
89 
90 	// Reset GLES state
91 	gl.bindTexture(GL_TEXTURE_2D, 0);
92 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
93 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
94 
95 	gl.deleteTextures(1, &m_to_id);
96 	gl.deleteFramebuffers(1, &m_fbo_id);
97 	gl.deleteBuffers(1, &m_vbo_id);
98 
99 	delete m_program;
100 
101 	// Deinitialize base class
102 	TestCaseBase::deinit();
103 }
104 
105 /// Generate Vertex Shader string
genVS() const106 std::string FragmentShadingRateAttachment::genVS() const
107 {
108 	std::ostringstream os;
109 	os << "#version 310 es\n";
110 
111 	if (m_tcParam.testKind == TestKind::MultiView)
112 	{
113 		os << "#extension GL_OVR_multiview: enable\n"
114 			  "layout(num_views = 2) in;\n";
115 	}
116 
117 	os << "precision highp float;\n"
118 	   << "precision highp int;\n"
119 	   << "uniform int drawID;\n"
120 	   << "layout(location = 0) in vec4 position;\n"
121 	   << "void main() {\n"
122 	   << "    gl_Position = position;\n";
123 	if (m_tcParam.testKind == TestKind::MultiView)
124 	{
125 		os << "if (gl_ViewID_OVR == 1u) {\n"
126 		   << "gl_Position.x  += 0.1;\n"
127 		   << "}\n";
128 	}
129 	os << "}";
130 	return os.str();
131 }
132 
133 /// Generate Fragment Shader string
genFS() const134 std::string FragmentShadingRateAttachment::genFS() const
135 {
136 	std::ostringstream os;
137 	os << "#version 310 es\n"
138 	   << "#extension GL_EXT_fragment_shading_rate : enable\n"
139 	   << "precision highp float;\n"
140 	   << "precision highp int;\n"
141 	   << "layout(location = 0) out ivec4 color0;\n"
142 	   << "uniform int drawID;\n"
143 	   << "void main() {\n"
144 	   << "    color0.x = gl_ShadingRateEXT;\n"
145 	   << "    color0.y = drawID;\n"
146 	   << "    color0.z = 0;\n"
147 	   << "    color0.w = 0;\n"
148 	   << "}";
149 
150 	return os.str();
151 }
152 
153 /// Initializes all GLES objects and reference values for the test.
setupTest(void)154 void FragmentShadingRateAttachment::setupTest(void)
155 {
156 	m_program =
157 		new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(genVS().c_str(), genFS().c_str()));
158 
159 	if (!m_program->isOk())
160 	{
161 		m_testCtx.getLog() << tcu::TestLog::Message << "" << tcu::TestLog::EndMessage
162 						   << tcu::TestLog::ShaderProgram(false, "")
163 						   << tcu::TestLog::Shader(QP_SHADER_TYPE_VERTEX,
164 												   m_program->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).source, false,
165 												   m_program->getShaderInfo(glu::SHADERTYPE_VERTEX, 0).infoLog)
166 
167 						   << tcu::TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,
168 												   m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).source, false,
169 												   m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT, 0).infoLog)
170 						   << tcu::TestLog::EndShaderProgram;
171 		TCU_FAIL("Shader creation failed");
172 	}
173 
174 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
175 
176 	// Generate framebuffer objects
177 	gl.genFramebuffers(1, &m_fbo_id);
178 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting up framebuffer objects");
179 
180 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
181 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");
182 
183 	// Generate a new texture name
184 	gl.genTextures(1, &m_to_id);
185 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture objects");
186 
187 	if (m_tcParam.layerCount > 1)
188 	{
189 		// Allocate unsigned integer storage
190 		gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_id);
191 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
192 
193 		gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA32UI, m_tcParam.framebufferSize, m_tcParam.framebufferSize,
194 						m_tcParam.layerCount);
195 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
196 	}
197 	else
198 	{
199 		// Allocate unsigned integer storage
200 		gl.bindTexture(GL_TEXTURE_2D, m_to_id);
201 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
202 
203 		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, m_tcParam.framebufferSize, m_tcParam.framebufferSize);
204 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
205 	}
206 
207 	// Attach it to the framebuffer
208 	if (m_tcParam.testKind == TestKind::MultiView)
209 	{
210 		gl.framebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0, 0,
211 										  m_tcParam.layerCount);
212 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
213 	}
214 	else
215 	{
216 		gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0);
217 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");
218 	}
219 
220 	// Generate a shading rate texture name
221 	if (m_tcParam.attachmentShadingRate)
222 	{
223 		// generate shading rate texture
224 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT, &m_srTexelWidth);
225 		GLU_EXPECT_NO_ERROR(gl.getError(),
226 							"Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT!");
227 		gl.getIntegerv(GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT, &m_srTexelHeight);
228 		GLU_EXPECT_NO_ERROR(gl.getError(),
229 							"Error getIntegerv GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT!");
230 
231 		const deUint32 srWidth	= (m_tcParam.framebufferSize + m_srTexelWidth - 1) / m_srTexelWidth;
232 		const deUint32 srHeight = (m_tcParam.framebufferSize + m_srTexelHeight - 1) / m_srTexelHeight;
233 
234 		std::vector<deUint8> attachmentShadingRateData;
235 		const deUint32		 srLayerCount = m_tcParam.multiShadingRate ? 2 : 1;
236 		attachmentShadingRateData.reserve(srWidth * srHeight * srLayerCount);
237 		for (deUint32 srLayer = 0; srLayer < srLayerCount; srLayer++)
238 		{
239 			for (deUint32 y = 0; y < srHeight; y++)
240 			{
241 				for (deUint32 x = 0; x < srWidth; x++)
242 				{
243 					deUint8 packedShadingRate = static_cast<unsigned char>(
244 						fsrutils::packShadingRate(translateCoordsToShadingRate(srLayer, x, y)));
245 					attachmentShadingRateData.push_back(packedShadingRate);
246 				}
247 			}
248 		}
249 
250 		gl.genTextures(1, &m_sr_to_id);
251 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture objects");
252 		gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
253 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error set pixelStorei for unpack alignment");
254 
255 		if (m_tcParam.multiShadingRate)
256 		{
257 			DE_ASSERT(m_tcParam.layerCount > 1);
258 			// Allocate unsigned integer storage
259 			gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_sr_to_id);
260 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
261 
262 			gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R8UI, srWidth, srHeight, m_tcParam.layerCount);
263 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
264 
265 			gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, srWidth, srHeight, m_tcParam.layerCount, GL_RED_INTEGER,
266 							 GL_UNSIGNED_BYTE, attachmentShadingRateData.data());
267 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error updating shading rate data to texture");
268 
269 			// Attach it to the framebuffer
270 			gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, m_sr_to_id, 0,
271 										 m_tcParam.layerCount, m_srTexelWidth, m_srTexelHeight);
272 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error framebufferShadingRate");
273 		}
274 		else
275 		{
276 			// Allocate unsigned integer storage
277 			gl.bindTexture(GL_TEXTURE_2D, m_sr_to_id);
278 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");
279 
280 			gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8UI, srWidth, srHeight);
281 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object!");
282 
283 			gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, srWidth, srHeight, GL_RED_INTEGER, GL_UNSIGNED_BYTE,
284 							 attachmentShadingRateData.data());
285 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error updating shading rate data to texture");
286 
287 			// Attach it to the framebuffer
288 			gl.framebufferShadingRateEXT(GL_FRAMEBUFFER, GL_SHADING_RATE_ATTACHMENT_EXT, m_sr_to_id, 0, 1,
289 										 m_srTexelWidth, m_srTexelHeight);
290 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error framebufferShadingRate");
291 		}
292 	}
293 
294 	constexpr deUint32 kVerticesCount = (TRIANGLE_COUNT * 3 * 2);
295 	std::vector<float> randomVertices;
296 	randomVertices.reserve(kVerticesCount);
297 
298 	// 1st draw triangle is huge to fill all rect.
299 	randomVertices.push_back(-3.0);
300 	randomVertices.push_back(-3.0);
301 	randomVertices.push_back(-3.0);
302 	randomVertices.push_back(3.0);
303 	randomVertices.push_back(3.0);
304 	randomVertices.push_back(-3.0);
305 
306 	deRandom rnd;
307 	deRandom_init(&rnd, 0);
308 	for (deUint32 i = 0; i < kVerticesCount; i++)
309 	{
310 		randomVertices.push_back((deRandom_getFloat(&rnd) * 2.0f - 1.0f));
311 	}
312 
313 	gl.genBuffers(1, &m_vbo_id);
314 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generate buffer objects");
315 
316 	gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
317 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer objects");
318 
319 	gl.bufferData(GL_ARRAY_BUFFER, randomVertices.size() * sizeof(float), randomVertices.data(), GL_STATIC_DRAW);
320 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error uploading buffer data");
321 
322 	if (m_tcParam.testKind == TestKind::Scissor)
323 	{
324 		m_scissorBox = { m_tcParam.framebufferSize / 3, m_tcParam.framebufferSize / 3, m_tcParam.framebufferSize / 3,
325 						 m_tcParam.framebufferSize / 3 };
326 	}
327 }
328 
329 /// Executes the test.
330 ///  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
331 ///  Note the function throws exception should an error occur!
332 ///
333 ///  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
334 ///
iterate(void)335 tcu::TestNode::IterateResult FragmentShadingRateAttachment::iterate(void)
336 {
337 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
338 
339 	// Initialization
340 	constexpr deUint32 kMaxRateCount =
341 		16; // SHADING_RATE_1X1_PIXELS_EXT ~ SHADING_RATE_4X4_PIXELS_EXT, actually 9 is enough
342 	glw::GLenum	 shadingRates[kMaxRateCount];
343 	glw::GLsizei count = 0;
344 
345 	gl.getFragmentShadingRatesEXT(1, kMaxRateCount, &count, shadingRates);
346 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error to get shading rate getFragmentShadingRatesEXT");
347 	DE_ASSERT(count > 0);
348 
349 	for (glw::GLsizei i = 0; i < count; i++)
350 	{
351 		m_availableShadingRates.push_back(shadingRates[i]);
352 	}
353 
354 	setupTest();
355 
356 	gl.disable(GL_DEPTH_TEST);
357 
358 	gl.shadingRateEXT(GL_SHADING_RATE_1X1_PIXELS_EXT);
359 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error to set shadingRateEXT as default");
360 
361 	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
362 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error clear Color");
363 
364 	gl.clear(GL_COLOR_BUFFER_BIT);
365 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error clear");
366 
367 	gl.useProgram(m_program->getProgram());
368 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error use program");
369 
370 	gl.bindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
371 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error bind buffer vertex data");
372 
373 	gl.enableVertexAttribArray(0);
374 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error enabling vertex attrib pointer 0");
375 
376 	gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
377 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex attrib pointer 0");
378 
379 	if (m_tcParam.attachmentShadingRate)
380 	{
381 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT,
382 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT);
383 	}
384 	else
385 	{
386 		gl.shadingRateCombinerOpsEXT(GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT,
387 									 GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT);
388 	}
389 
390 	if (m_tcParam.testKind == TestKind::Scissor)
391 	{
392 		gl.scissor(m_scissorBox.x, m_scissorBox.y, m_scissorBox.width, m_scissorBox.height);
393 		gl.enable(GL_SCISSOR_TEST);
394 	}
395 
396 	// draw ID start from 1
397 	for (deUint32 drawID = 1; drawID < TRIANGLE_COUNT; drawID++)
398 	{
399 		gl.uniform1i(gl.getUniformLocation(m_program->getProgram(), "drawID"), drawID);
400 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error set uniform drawID value");
401 
402 		if (!m_tcParam.attachmentShadingRate)
403 		{
404 			gl.shadingRateEXT(translateDrawIDToShadingRate(drawID));
405 			GLU_EXPECT_NO_ERROR(gl.getError(), "Error set shading rate");
406 		}
407 
408 		const deUint32 startVertex = (drawID - 1) * 2; // to use first vertices "-1" because drawID start from 1
409 		gl.drawArrays(GL_TRIANGLES, startVertex, 3);
410 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error draw a triangle");
411 	}
412 
413 	for (uint32_t layer = 0; layer < m_tcParam.layerCount; layer++)
414 	{
415 		if (m_tcParam.layerCount > 1)
416 		{
417 			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0, layer);
418 		}
419 		const deUint32		  dataSize = m_tcParam.framebufferSize * m_tcParam.framebufferSize * 4;
420 		std::vector<deUint32> resultData(dataSize);
421 		gl.readPixels(0, 0, m_tcParam.framebufferSize, m_tcParam.framebufferSize, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
422 					  resultData.data());
423 		GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from frame buffer!");
424 
425 		for (deUint32 y = 0; y < m_tcParam.framebufferSize; y++)
426 		{
427 			for (deUint32 x = 0; x < m_tcParam.framebufferSize; x++)
428 			{
429 				const deUint32* sample = &resultData[((y * m_tcParam.framebufferSize) + x) * 4];
430 
431 				if (m_tcParam.testKind == TestKind::Scissor)
432 				{
433 					if (!m_scissorBox.in(x, y)) // out of scissor box
434 					{
435 						if (sample[1] != 0) // should be cleared to 0
436 						{
437 							std::stringstream error_sstream;
438 							error_sstream << "out of scissor box should be 0"
439 										  << "scissor: " << m_scissorBox.x << " " << m_scissorBox.width << " "
440 										  << m_scissorBox.y << " " << m_scissorBox.height;
441 						}
442 						else
443 						{
444 							// success. outside scissor is always 0
445 							continue;
446 						}
447 					}
448 					else
449 					{
450 						if (sample[1] == 0) // if it is cleared to 0, error. All cleared by 1st big triangle
451 						{
452 							std::stringstream error_sstream;
453 							error_sstream << "inside of scissor box should not be 0"
454 										  << "scissor: " << m_scissorBox.x << " " << m_scissorBox.width << " "
455 										  << m_scissorBox.y << " " << m_scissorBox.height;
456 						}
457 					}
458 				}
459 				else if (sample[1] == 0) // nothing rendered for the other case except scissor test
460 				{
461 					continue;
462 				}
463 
464 				const deUint32 shadingRate = sample[0];
465 				const deUint32 drawID	   = sample[1];
466 
467 				deUint32 expectedShadingRate = 0;
468 				if (m_tcParam.attachmentShadingRate)
469 				{
470 					deUint32 srLayer = m_tcParam.multiShadingRate ? layer : 0;
471 					expectedShadingRate = fsrutils::packShadingRate(
472 						translateCoordsToShadingRate(srLayer, x / m_srTexelWidth, y / m_srTexelHeight));
473 				}
474 				else
475 				{
476 					expectedShadingRate = fsrutils::packShadingRate(translateDrawIDToShadingRate(drawID));
477 				}
478 
479 				if (expectedShadingRate != shadingRate)
480 				{
481 					std::stringstream error_sstream;
482 
483 					error_sstream << "The draw ID is " << drawID << "Shading Rate is" << shadingRate
484 								  << ", But we expect " << expectedShadingRate;
485 
486 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, error_sstream.str().c_str());
487 
488 					return STOP;
489 				}
490 			}
491 		}
492 	}
493 
494 	// All done
495 	if (m_testCtx.getTestResult() != QP_TEST_RESULT_FAIL)
496 	{
497 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
498 	}
499 
500 	return STOP;
501 }
502 
503 /// Translate draw ID to ShadingRate enumeration
504 ///
505 /// @param drawID draw ID to translate shading rate
506 ///
507 /// @return shading rate enumeration
translateDrawIDToShadingRate(deUint32 drawID) const508 glw::GLenum FragmentShadingRateAttachment::translateDrawIDToShadingRate(deUint32 drawID) const
509 {
510 	return m_availableShadingRates[drawID % m_availableShadingRates.size()];
511 }
512 
513 /// translate draw ID to View ID
514 ///
515 /// @param drawID ID to translate to View ID
516 ///
517 /// @return translated ViewID
drawIDToViewID(deUint32 drawID) const518 deUint32 FragmentShadingRateAttachment::drawIDToViewID(deUint32 drawID) const
519 {
520 	return drawID & 1;
521 }
522 
523 /// Translate Coordinates ID to ShadingRate enumeration
524 ///
525 ///@param srLayer shading rate layer index
526 ///@param srx x coord in the shading rate attachment to translate shading rate
527 ///@param sry y coord in the shading rate attachment to translate shading rate
528 ///
529 ///@return shading rate enumeration
translateCoordsToShadingRate(deUint32 srLayer,deUint32 srx,deUint32 sry) const530 glw::GLenum FragmentShadingRateAttachment::translateCoordsToShadingRate(deUint32 srLayer, deUint32 srx,
531 																		deUint32 sry) const
532 {
533 	DE_ASSERT(m_tcParam.multiShadingRate || srLayer == 0);
534 	return m_availableShadingRates[(srLayer + srx + sry) % m_availableShadingRates.size()];
535 }
536 
537 } // namespace glcts
538