• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  * Copyright (c) 2019-2020 NVIDIA Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Fragment Shading Rate tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktFragmentShadingRateTests.hpp"
26 #include "vktFragmentShadingRateBasic.hpp"
27 #include "vktFragmentShadingRatePixelConsistency.hpp"
28 #include "vktAttachmentRateTests.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vktTestCaseUtil.hpp"
31 #include "tcuTestLog.hpp"
32 #include <limits>
33 
34 namespace vkt
35 {
36 namespace FragmentShadingRate
37 {
38 
39 namespace
40 {
41 
testLimits(Context & context)42 tcu::TestStatus testLimits(Context& context)
43 {
44 	bool			allChecksPassed					= true;
45 	tcu::TestLog&	log								= context.getTestContext().getLog();
46 	const auto&		features						= context.getDeviceFeatures();
47 	const auto&		properties						= context.getDeviceProperties();
48 	const auto&		vulkan12Features				= context.getDeviceVulkan12Features();
49 	const auto&		fragmentShadingRateFeatures		= context.getFragmentShadingRateFeatures();
50 	const auto&		fragmentShadingRateProperties	= context.getFragmentShadingRateProperties();
51 
52 	if (!fragmentShadingRateFeatures.pipelineFragmentShadingRate)
53 	{
54 		log << tcu::TestLog::Message << "pipelineFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
55 		allChecksPassed = false;
56 	}
57 
58 	if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports && !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
59 	{
60 		log << tcu::TestLog::Message << "primitiveFragmentShadingRateWithMultipleViewports "
61 										"limit should only be supported if primitiveFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
62 		allChecksPassed = false;
63 	}
64 
65 	bool requiredFeatures = features.geometryShader || vulkan12Features.shaderOutputViewportIndex || context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
66 	if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports && !requiredFeatures)
67 	{
68 		log << tcu::TestLog::Message << "primitiveFragmentShadingRateWithMultipleViewports limit should only "
69 										"be supported if at least one of the geometryShader feature, shaderOutputViewportIndex feature, "
70 										"or VK_EXT_shader_viewport_index_layer extension is supported" << tcu::TestLog::EndMessage;
71 		allChecksPassed = false;
72 	}
73 
74 	if (fragmentShadingRateProperties.layeredShadingRateAttachments && !fragmentShadingRateFeatures.attachmentFragmentShadingRate)
75 	{
76 		log << tcu::TestLog::Message << "layeredShadingRateAttachments should only be supported if attachmentFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
77 		allChecksPassed = false;
78 	}
79 
80 	requiredFeatures = features.geometryShader || context.getMultiviewFeatures().multiview || vulkan12Features.shaderOutputViewportIndex ||
81 						context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
82 	if (fragmentShadingRateProperties.layeredShadingRateAttachments && !requiredFeatures)
83 	{
84 		log << tcu::TestLog::Message << "layeredShadingRateAttachments should only be supported if at least one of the geometryShader feature, multiview feature, "
85 										"shaderOutputViewportIndex feature, or VK_EXT_shader_viewport_index_layer extension is supported" << tcu::TestLog::EndMessage;
86 		allChecksPassed = false;
87 	}
88 
89 	requiredFeatures = fragmentShadingRateFeatures.primitiveFragmentShadingRate || fragmentShadingRateFeatures.attachmentFragmentShadingRate;
90 	if (fragmentShadingRateProperties.fragmentShadingRateNonTrivialCombinerOps && !requiredFeatures)
91 	{
92 		log << tcu::TestLog::Message << "fragmentShadingRateNonTrivialCombinerOps should only be supported if at least one of primitiveFragmentShadingRate "
93 										"or attachmentFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
94 		allChecksPassed = false;
95 	}
96 
97 	if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio > std::max(fragmentShadingRateProperties.maxFragmentSize.width, fragmentShadingRateProperties.maxFragmentSize.height))
98 	{
99 		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be less than or equal to the maximum width / height of maxFragmentSize" << tcu::TestLog::EndMessage;
100 		allChecksPassed = false;
101 	}
102 
103 	if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio < 2)
104 	{
105 		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be at least 2" << tcu::TestLog::EndMessage;
106 		allChecksPassed = false;
107 	}
108 
109 	if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentSizeAspectRatio)))
110 	{
111 		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be power of 2" << tcu::TestLog::EndMessage;
112 		allChecksPassed = false;
113 	}
114 
115 	if (fragmentShadingRateProperties.fragmentShadingRateWithShaderSampleMask && (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples > (properties.limits.maxSampleMaskWords * 32)))
116 	{
117 		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should be less than or equal maxSampleMaskWords * 32 "
118 										"if fragmentShadingRateWithShaderSampleMask is supported" << tcu::TestLog::EndMessage;
119 		allChecksPassed = false;
120 	}
121 
122 	deUint32 requiredValue = fragmentShadingRateProperties.maxFragmentSize.width * fragmentShadingRateProperties.maxFragmentSize.height *
123 								fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples;
124 	if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples > requiredValue)
125 	{
126 		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should be less than or equal to the product of the width and height of "
127 										"maxFragmentSize and the samples reported by maxFragmentShadingRateRasterizationSamples" << tcu::TestLog::EndMessage;
128 		allChecksPassed = false;
129 	}
130 
131 	if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples < 16)
132 	{
133 		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should at least be 16" << tcu::TestLog::EndMessage;
134 		allChecksPassed = false;
135 	}
136 
137 	if (fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples < vk::VK_SAMPLE_COUNT_4_BIT)
138 	{
139 		log << tcu::TestLog::Message << "maxFragmentShadingRateRasterizationSamples should supports at least VK_SAMPLE_COUNT_4_BIT" << tcu::TestLog::EndMessage;
140 		allChecksPassed = false;
141 	}
142 
143 	if (fragmentShadingRateProperties.fragmentShadingRateWithConservativeRasterization && !context.isDeviceFunctionalitySupported("VK_EXT_conservative_rasterization"))
144 	{
145 		log << tcu::TestLog::Message << "fragmentShadingRateWithConservativeRasterization should only be supported if VK_EXT_conservative_rasterization is supported" << tcu::TestLog::EndMessage;
146 		allChecksPassed = false;
147 	}
148 
149 	if (fragmentShadingRateProperties.fragmentShadingRateWithFragmentShaderInterlock && !context.isDeviceFunctionalitySupported("VK_EXT_fragment_shader_interlock"))
150 	{
151 		log << tcu::TestLog::Message << "fragmentShadingRateWithFragmentShaderInterlock should only be supported if VK_EXT_fragment_shader_interlock is supported" << tcu::TestLog::EndMessage;
152 		allChecksPassed = false;
153 	}
154 
155 	if (fragmentShadingRateProperties.fragmentShadingRateWithCustomSampleLocations && !context.isDeviceFunctionalitySupported("VK_EXT_sample_locations"))
156 	{
157 		log << tcu::TestLog::Message << "fragmentShadingRateWithCustomSampleLocations should only be supported if VK_EXT_sample_locations is supported" << tcu::TestLog::EndMessage;
158 		allChecksPassed = false;
159 	}
160 
161 	if (fragmentShadingRateFeatures.attachmentFragmentShadingRate)
162 	{
163 		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < 8) ||
164 			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < 8))
165 		{
166 			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should at least be { 8,8 }" << tcu::TestLog::EndMessage;
167 			allChecksPassed = false;
168 		}
169 
170 		if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width > 32) ||
171 			(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height > 32))
172 		{
173 			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should't be greater than { 32,32 }" << tcu::TestLog::EndMessage;
174 			allChecksPassed = false;
175 		}
176 
177 		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width) ||
178 			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height))
179 		{
180 			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be greater than or equal to "
181 				"minFragmentShadingRateAttachmentTexelSize in each dimension" << tcu::TestLog::EndMessage;
182 			allChecksPassed = false;
183 		}
184 
185 		if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width)) ||
186 			!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height)))
187 		{
188 			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be power of 2" << tcu::TestLog::EndMessage;
189 			allChecksPassed = false;
190 		}
191 
192 		if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width)) ||
193 			!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height)))
194 		{
195 			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should be power of 2" << tcu::TestLog::EndMessage;
196 			allChecksPassed = false;
197 		}
198 	}
199 	else
200 	{
201 		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width != 0) ||
202 			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height != 0))
203 		{
204 			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
205 											"attachmentFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
206 			allChecksPassed = false;
207 		}
208 
209 		if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width != 0) ||
210 			(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height != 0))
211 		{
212 			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
213 											"attachmentFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
214 			allChecksPassed = false;
215 		}
216 	}
217 
218 	if ((fragmentShadingRateProperties.maxFragmentSize.width < 2) ||
219 		(fragmentShadingRateProperties.maxFragmentSize.height < 2))
220 	{
221 		log << tcu::TestLog::Message << "maxFragmentSize should at least be { 2,2 }" << tcu::TestLog::EndMessage;
222 		allChecksPassed = false;
223 	}
224 
225 	if ((fragmentShadingRateProperties.maxFragmentSize.width > 4) ||
226 		(fragmentShadingRateProperties.maxFragmentSize.height > 4))
227 	{
228 		log << tcu::TestLog::Message << "maxFragmentSize should't be greater than{ 4,4 }" << tcu::TestLog::EndMessage;
229 		allChecksPassed = false;
230 	}
231 
232 	if (allChecksPassed)
233 		return tcu::TestStatus::pass("pass");
234 	return tcu::TestStatus::fail("fail");
235 }
236 
testShadingRates(Context & context)237 tcu::TestStatus testShadingRates(Context& context)
238 {
239 	bool							someChecksFailed					= false;
240 	tcu::TestLog&					log									= context.getTestContext().getLog();
241 	const vk::InstanceInterface&	vki									= context.getInstanceInterface();
242 	vk::VkPhysicalDevice			physicalDevice						= context.getPhysicalDevice();
243 	const auto&						fragmentShadingRateProperties		= context.getFragmentShadingRateProperties();
244 	deUint32						supportedFragmentShadingRateCount	= 0;
245 
246 	vk::VkResult result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, DE_NULL);
247 	if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
248 	{
249 		someChecksFailed = true;
250 		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
251 	}
252 
253 	std::vector<vk::VkPhysicalDeviceFragmentShadingRateKHR> fragmentShadingRateVect(supportedFragmentShadingRateCount);
254 	for (auto& fragmentShadingRate : fragmentShadingRateVect)
255 	{
256 		fragmentShadingRate.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
257 		fragmentShadingRate.pNext = DE_NULL;
258 	}
259 
260 	// Pass a value of 1 into pFragmentShadingRateCount, and an array of at least length one into pFragmentShadingRates.
261 	// Check that the returned value is either VK_INCOMPLETE or VK_ERROR_OUT_OF_HOST_MEMORY(and issue a quality warning in the latter case).
262 	supportedFragmentShadingRateCount = 1u;
263 	result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, fragmentShadingRateVect.data());
264 	if ((result != vk::VK_INCOMPLETE) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
265 	{
266 		someChecksFailed = true;
267 		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
268 	}
269 
270 	// Get all available fragment shading rates
271 	supportedFragmentShadingRateCount = static_cast<deUint32>(fragmentShadingRateVect.size());
272 	result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, fragmentShadingRateVect.data());
273 	if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
274 	{
275 		someChecksFailed = true;
276 		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
277 	}
278 
279 	bool		widthCheckPassed	= true;
280 	bool		heightCheckPassed	= true;
281 	deUint32	previousWidth		= std::numeric_limits<deUint32>::max();
282 	deUint32	previousHeight		= std::numeric_limits<deUint32>::max();
283 
284 	for (const auto& fsr : fragmentShadingRateVect)
285 	{
286 		const auto& fragmentSize = fsr.fragmentSize;
287 
288 		// Check that rate width and height are power-of-two
289 		if (!deIntIsPow2(static_cast<int>(fragmentSize.width)) ||
290 			!deIntIsPow2(static_cast<int>(fragmentSize.height)))
291 		{
292 			log << tcu::TestLog::Message << "fragmentSize should be power of 2" << tcu::TestLog::EndMessage;
293 			someChecksFailed = true;
294 		}
295 
296 		// Check that the width and height are less than the values in the maxFragmentSize limit
297 		if ((fragmentSize.width > fragmentShadingRateProperties.maxFragmentSize.width) ||
298 			(fragmentSize.height > fragmentShadingRateProperties.maxFragmentSize.height))
299 		{
300 			log << tcu::TestLog::Message << "fragmentSize width and height are not less than the values in the maxFragmentSize" << tcu::TestLog::EndMessage;
301 			someChecksFailed = true;
302 		}
303 
304 		if ((fragmentSize.width * fragmentSize.height) == 1)
305 		{
306 			// special case for fragmentSize {1, 1}
307 			if (fsr.sampleCounts != ~0u)
308 			{
309 				log << tcu::TestLog::Message << "implementations must support sampleCounts equal to ~0 for fragmentSize {1, 1}" << tcu::TestLog::EndMessage;
310 				someChecksFailed = true;
311 			}
312 		}
313 		else
314 		{
315 			// get highest sample count value
316 			deUint32 highestSampleCount = 0x80000000;
317 			while (highestSampleCount)
318 			{
319 				if (fsr.sampleCounts & highestSampleCount)
320 					break;
321 				highestSampleCount >>= 1;
322 			}
323 
324 			// Check that the highest sample count in sampleCounts is less than or equal to maxFragmentShadingRateRasterizationSamples limit
325 			if (highestSampleCount > static_cast<deUint32>(fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples))
326 			{
327 				log << tcu::TestLog::Message << "highest sample count value is not less than or equal to the maxFragmentShadingRateRasterizationSamples limit" << tcu::TestLog::EndMessage;
328 				someChecksFailed = true;
329 			}
330 
331 			// Check that the product of the width, height, and highest sample count value is less than the maxFragmentShadingRateCoverageSamples limit
332 			if ((fragmentSize.width * fragmentSize.height * highestSampleCount) > fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples)
333 			{
334 				log << tcu::TestLog::Message << "product of the width, height, and highest sample count value is not less than the maxFragmentShadingRateCoverageSamples limit" << tcu::TestLog::EndMessage;
335 				someChecksFailed = true;
336 			}
337 		}
338 
339 		// Check that the entries in the array are ordered first by largest to smallest width, then largest to smallest height
340 		{
341 			const deUint32 currentWidth = fragmentSize.width;
342 			if (widthCheckPassed && (currentWidth > previousWidth))
343 			{
344 				log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries that are not ordered by largest to smallest width" << tcu::TestLog::EndMessage;
345 				widthCheckPassed = false;
346 			}
347 
348 			deUint32 currentHeight = fragmentSize.height;
349 			if (heightCheckPassed)
350 			{
351 				// we can check order of height only for entries that have same width
352 				if (currentWidth == previousWidth)
353 				{
354 					if (currentHeight > previousHeight)
355 					{
356 						log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same width but height is not ordered by largest to smallest" << tcu::TestLog::EndMessage;
357 						heightCheckPassed = false;
358 					}
359 				}
360 				else
361 					currentHeight = std::numeric_limits<deUint32>::max();
362 			}
363 
364 			previousWidth = currentWidth;
365 			previousHeight = currentHeight;
366 		}
367 
368 		// Check that no two entries in the array have the same fragmentSize.width and fragmentSize.height value
369 		{
370 			deUint32 count = 0;
371 			for (const auto& fsrB : fragmentShadingRateVect)
372 			{
373 				if ((fragmentSize.width  == fsrB.fragmentSize.width) &&
374 					(fragmentSize.height == fsrB.fragmentSize.height))
375 				{
376 					if (++count > 1)
377 					{
378 						log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same fragmentSize" << tcu::TestLog::EndMessage;
379 						someChecksFailed = true;
380 						break;
381 					}
382 				}
383 			}
384 		}
385 
386 		// Check that 1x1, 1x2, 2x1, and 2x2 rates are supported with sample counts of 1 and 4
387 		if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
388 			(!(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) || !(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_4_BIT)))
389 		{
390 			log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample counts not supporting 1 and 4" << tcu::TestLog::EndMessage;
391 			someChecksFailed = true;
392 		}
393 
394 		// If the framebufferColorSampleCounts limit includes a sample count of 2, ensure that a sample count of 2 is also reported for the 1x1, 1x2, 2x1, and 2x2 rates.
395 		if (context.getDeviceProperties().limits.framebufferColorSampleCounts & vk::VK_SAMPLE_COUNT_2_BIT)
396 		{
397 			if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
398 				!(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_2_BIT))
399 			{
400 				log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample counts not supporting 2 while framebufferColorSampleCounts does" << tcu::TestLog::EndMessage;
401 				someChecksFailed = true;
402 			}
403 		}
404 	}
405 
406 	if (someChecksFailed || !widthCheckPassed || !heightCheckPassed)
407 		return tcu::TestStatus::fail("fail");
408 
409 	return tcu::TestStatus::pass("pass");
410 }
411 
checkSupport(Context & context)412 void checkSupport(Context& context)
413 {
414 	context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
415 }
416 
createMiscTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * parentGroup)417 void createMiscTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup)
418 {
419 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc", ""));
420 
421 	addFunctionCase(group.get(), "limits",			"", checkSupport, testLimits);
422 	addFunctionCase(group.get(), "shading_rates",	"", checkSupport, testShadingRates);
423 
424 	parentGroup->addChild(group.release());
425 }
426 
createChildren(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,bool useDynamicRendering)427 void createChildren (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, bool useDynamicRendering)
428 {
429 	createBasicTests(testCtx, group, useDynamicRendering);
430 
431 	if (!useDynamicRendering)
432 	{
433 		// there is no point in duplicating those tests for dynamic rendering
434 		createMiscTests(testCtx, group);
435 
436 		// subpasses can't be translated to dynamic rendering
437 		createPixelConsistencyTests(testCtx, group);
438 
439 		createAttachmentRateTests(testCtx, group);
440 	}
441 }
442 
443 } // anonymous
444 
createTests(tcu::TestContext & testCtx)445 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
446 {
447 	de::MovePtr<tcu::TestCaseGroup> mainGroup				(new tcu::TestCaseGroup(testCtx, "fragment_shading_rate", "Fragment shading rate tests"));
448 	de::MovePtr<tcu::TestCaseGroup> renderpass2Group		(new tcu::TestCaseGroup(testCtx, "renderpass2", "Draw using render pass object"));
449 	de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup	(new tcu::TestCaseGroup(testCtx, "dynamic_rendering", "Draw using VK_KHR_dynamic_rendering"));
450 
451 	createChildren(testCtx, renderpass2Group.get(), false);
452 	createChildren(testCtx, dynamicRenderingGroup.get(), true);
453 
454 	mainGroup->addChild(renderpass2Group.release());
455 	mainGroup->addChild(dynamicRenderingGroup.release());
456 
457 	return mainGroup.release();
458 }
459 
460 } // FragmentShadingRate
461 } // vkt
462