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