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 "vktFragmentShadingRateGroupParams.hpp"
29 #include "vktAttachmentRateTests.hpp"
30 #include "vktFragmentShadingRateMiscTests.hpp"
31 #include "vktTestGroupUtil.hpp"
32 #include "vktTestCaseUtil.hpp"
33 #include "vkPipelineConstructionUtil.hpp"
34 #include "tcuTestLog.hpp"
35 #include <limits>
36
37 namespace vkt
38 {
39 namespace FragmentShadingRate
40 {
41
42 namespace
43 {
44
testLimits(Context & context)45 tcu::TestStatus testLimits(Context &context)
46 {
47 bool allChecksPassed = true;
48 tcu::TestLog &log = context.getTestContext().getLog();
49 const auto &features = context.getDeviceFeatures();
50 const auto &properties = context.getDeviceProperties();
51 const auto &vulkan12Features = context.getDeviceVulkan12Features();
52 const auto &fragmentShadingRateFeatures = context.getFragmentShadingRateFeatures();
53 const auto &fragmentShadingRateProperties = context.getFragmentShadingRateProperties();
54
55 if (!fragmentShadingRateFeatures.pipelineFragmentShadingRate)
56 {
57 log << tcu::TestLog::Message << "pipelineFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
58 allChecksPassed = false;
59 }
60
61 if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports &&
62 !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
63 {
64 log << tcu::TestLog::Message
65 << "primitiveFragmentShadingRateWithMultipleViewports "
66 "limit should only be supported if primitiveFragmentShadingRate is supported"
67 << tcu::TestLog::EndMessage;
68 allChecksPassed = false;
69 }
70
71 bool requiredFeatures = features.geometryShader || vulkan12Features.shaderOutputViewportIndex ||
72 context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
73 if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports &&
74 !requiredFeatures)
75 {
76 log << tcu::TestLog::Message
77 << "primitiveFragmentShadingRateWithMultipleViewports limit should only "
78 "be supported if at least one of the geometryShader feature, shaderOutputViewportIndex feature, "
79 "or VK_EXT_shader_viewport_index_layer extension is supported"
80 << tcu::TestLog::EndMessage;
81 allChecksPassed = false;
82 }
83
84 if (fragmentShadingRateProperties.layeredShadingRateAttachments &&
85 !fragmentShadingRateFeatures.attachmentFragmentShadingRate)
86 {
87 log << tcu::TestLog::Message
88 << "layeredShadingRateAttachments should only be supported if attachmentFragmentShadingRate is supported"
89 << tcu::TestLog::EndMessage;
90 allChecksPassed = false;
91 }
92
93 requiredFeatures = features.geometryShader || context.getMultiviewFeatures().multiview ||
94 vulkan12Features.shaderOutputViewportIndex ||
95 context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
96 if (fragmentShadingRateProperties.layeredShadingRateAttachments && !requiredFeatures)
97 {
98 log << tcu::TestLog::Message
99 << "layeredShadingRateAttachments should only be supported if at least one of the geometryShader feature, "
100 "multiview feature, "
101 "shaderOutputViewportIndex feature, or VK_EXT_shader_viewport_index_layer extension is supported"
102 << tcu::TestLog::EndMessage;
103 allChecksPassed = false;
104 }
105
106 requiredFeatures = fragmentShadingRateFeatures.primitiveFragmentShadingRate ||
107 fragmentShadingRateFeatures.attachmentFragmentShadingRate;
108 if (fragmentShadingRateProperties.fragmentShadingRateNonTrivialCombinerOps && !requiredFeatures)
109 {
110 log << tcu::TestLog::Message
111 << "fragmentShadingRateNonTrivialCombinerOps should only be supported if at least one of "
112 "primitiveFragmentShadingRate "
113 "or attachmentFragmentShadingRate is supported"
114 << tcu::TestLog::EndMessage;
115 allChecksPassed = false;
116 }
117
118 if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio >
119 std::max(fragmentShadingRateProperties.maxFragmentSize.width,
120 fragmentShadingRateProperties.maxFragmentSize.height))
121 {
122 log << tcu::TestLog::Message
123 << "maxFragmentSizeAspectRatio should be less than or equal to the maximum width / height of "
124 "maxFragmentSize"
125 << tcu::TestLog::EndMessage;
126 allChecksPassed = false;
127 }
128
129 if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio < 2)
130 {
131 log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be at least 2" << tcu::TestLog::EndMessage;
132 allChecksPassed = false;
133 }
134
135 if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentSizeAspectRatio)))
136 {
137 log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be power of 2" << tcu::TestLog::EndMessage;
138 allChecksPassed = false;
139 }
140
141 if (fragmentShadingRateProperties.fragmentShadingRateWithShaderSampleMask &&
142 (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples >
143 (properties.limits.maxSampleMaskWords * 32)))
144 {
145 log << tcu::TestLog::Message
146 << "maxFragmentShadingRateCoverageSamples should be less than or equal maxSampleMaskWords * 32 "
147 "if fragmentShadingRateWithShaderSampleMask is supported"
148 << tcu::TestLog::EndMessage;
149 allChecksPassed = false;
150 }
151
152 uint32_t requiredValue = fragmentShadingRateProperties.maxFragmentSize.width *
153 fragmentShadingRateProperties.maxFragmentSize.height *
154 fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples;
155 if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples > requiredValue)
156 {
157 log << tcu::TestLog::Message
158 << "maxFragmentShadingRateCoverageSamples should be less than or equal to the product of the width and "
159 "height of "
160 "maxFragmentSize and the samples reported by maxFragmentShadingRateRasterizationSamples"
161 << tcu::TestLog::EndMessage;
162 allChecksPassed = false;
163 }
164
165 if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples < 16)
166 {
167 log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should at least be 16"
168 << tcu::TestLog::EndMessage;
169 allChecksPassed = false;
170 }
171
172 if (fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples < vk::VK_SAMPLE_COUNT_4_BIT)
173 {
174 log << tcu::TestLog::Message
175 << "maxFragmentShadingRateRasterizationSamples should supports at least VK_SAMPLE_COUNT_4_BIT"
176 << tcu::TestLog::EndMessage;
177 allChecksPassed = false;
178 }
179
180 if (fragmentShadingRateProperties.fragmentShadingRateWithConservativeRasterization &&
181 !context.isDeviceFunctionalitySupported("VK_EXT_conservative_rasterization"))
182 {
183 log << tcu::TestLog::Message
184 << "fragmentShadingRateWithConservativeRasterization should only be supported if "
185 "VK_EXT_conservative_rasterization is supported"
186 << tcu::TestLog::EndMessage;
187 allChecksPassed = false;
188 }
189
190 if (fragmentShadingRateProperties.fragmentShadingRateWithFragmentShaderInterlock &&
191 !context.isDeviceFunctionalitySupported("VK_EXT_fragment_shader_interlock"))
192 {
193 log << tcu::TestLog::Message
194 << "fragmentShadingRateWithFragmentShaderInterlock should only be supported if "
195 "VK_EXT_fragment_shader_interlock is supported"
196 << tcu::TestLog::EndMessage;
197 allChecksPassed = false;
198 }
199
200 if (fragmentShadingRateProperties.fragmentShadingRateWithCustomSampleLocations &&
201 !context.isDeviceFunctionalitySupported("VK_EXT_sample_locations"))
202 {
203 log << tcu::TestLog::Message
204 << "fragmentShadingRateWithCustomSampleLocations should only be supported if VK_EXT_sample_locations is "
205 "supported"
206 << tcu::TestLog::EndMessage;
207 allChecksPassed = false;
208 }
209
210 if (fragmentShadingRateFeatures.attachmentFragmentShadingRate)
211 {
212 if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < 8) ||
213 (fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < 8))
214 {
215 log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should at least be { 8,8 }"
216 << tcu::TestLog::EndMessage;
217 allChecksPassed = false;
218 }
219
220 if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width > 32) ||
221 (fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height > 32))
222 {
223 log << tcu::TestLog::Message
224 << "minFragmentShadingRateAttachmentTexelSize should't be greater than { 32,32 }"
225 << tcu::TestLog::EndMessage;
226 allChecksPassed = false;
227 }
228
229 if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width <
230 fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width) ||
231 (fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height <
232 fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height))
233 {
234 log << tcu::TestLog::Message
235 << "maxFragmentShadingRateAttachmentTexelSize should be greater than or equal to "
236 "minFragmentShadingRateAttachmentTexelSize in each dimension"
237 << tcu::TestLog::EndMessage;
238 allChecksPassed = false;
239 }
240
241 if (!deIntIsPow2(
242 static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width)) ||
243 !deIntIsPow2(
244 static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height)))
245 {
246 log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be power of 2"
247 << tcu::TestLog::EndMessage;
248 allChecksPassed = false;
249 }
250
251 if (!deIntIsPow2(
252 static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width)) ||
253 !deIntIsPow2(
254 static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height)))
255 {
256 log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should be power of 2"
257 << tcu::TestLog::EndMessage;
258 allChecksPassed = false;
259 }
260 }
261 else
262 {
263 if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width != 0) ||
264 (fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height != 0))
265 {
266 log << tcu::TestLog::Message
267 << "maxFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
268 "attachmentFragmentShadingRate is not supported"
269 << tcu::TestLog::EndMessage;
270 allChecksPassed = false;
271 }
272
273 if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width != 0) ||
274 (fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height != 0))
275 {
276 log << tcu::TestLog::Message
277 << "minFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
278 "attachmentFragmentShadingRate is not supported"
279 << tcu::TestLog::EndMessage;
280 allChecksPassed = false;
281 }
282 }
283
284 if ((fragmentShadingRateProperties.maxFragmentSize.width < 2) ||
285 (fragmentShadingRateProperties.maxFragmentSize.height < 2))
286 {
287 log << tcu::TestLog::Message << "maxFragmentSize should at least be { 2,2 }" << tcu::TestLog::EndMessage;
288 allChecksPassed = false;
289 }
290
291 if ((fragmentShadingRateProperties.maxFragmentSize.width > 4) ||
292 (fragmentShadingRateProperties.maxFragmentSize.height > 4))
293 {
294 log << tcu::TestLog::Message << "maxFragmentSize should't be greater than{ 4,4 }" << tcu::TestLog::EndMessage;
295 allChecksPassed = false;
296 }
297
298 if (allChecksPassed)
299 return tcu::TestStatus::pass("pass");
300 return tcu::TestStatus::fail("fail");
301 }
302
testShadingRates(Context & context)303 tcu::TestStatus testShadingRates(Context &context)
304 {
305 bool someChecksFailed = false;
306 tcu::TestLog &log = context.getTestContext().getLog();
307 const vk::InstanceInterface &vki = context.getInstanceInterface();
308 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
309 const auto &fragmentShadingRateProperties = context.getFragmentShadingRateProperties();
310 uint32_t supportedFragmentShadingRateCount = 0;
311
312 vk::VkResult result =
313 vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, DE_NULL);
314 if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
315 {
316 someChecksFailed = true;
317 log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result"
318 << tcu::TestLog::EndMessage;
319 }
320
321 std::vector<vk::VkPhysicalDeviceFragmentShadingRateKHR> fragmentShadingRateVect(supportedFragmentShadingRateCount);
322 for (auto &fragmentShadingRate : fragmentShadingRateVect)
323 {
324 fragmentShadingRate.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
325 fragmentShadingRate.pNext = DE_NULL;
326 }
327
328 // Pass a value of 1 into pFragmentShadingRateCount, and an array of at least length one into pFragmentShadingRates.
329 // 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).
330 supportedFragmentShadingRateCount = 1u;
331 result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount,
332 fragmentShadingRateVect.data());
333 if ((result != vk::VK_INCOMPLETE) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
334 {
335 someChecksFailed = true;
336 log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result"
337 << tcu::TestLog::EndMessage;
338 }
339
340 // Get all available fragment shading rates
341 supportedFragmentShadingRateCount = static_cast<uint32_t>(fragmentShadingRateVect.size());
342 result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount,
343 fragmentShadingRateVect.data());
344 if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
345 {
346 someChecksFailed = true;
347 log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result"
348 << tcu::TestLog::EndMessage;
349 }
350
351 bool widthCheckPassed = true;
352 bool heightCheckPassed = true;
353 uint32_t previousWidth = std::numeric_limits<uint32_t>::max();
354 uint32_t previousHeight = std::numeric_limits<uint32_t>::max();
355
356 for (const auto &fsr : fragmentShadingRateVect)
357 {
358 const auto &fragmentSize = fsr.fragmentSize;
359
360 // Check that rate width and height are power-of-two
361 if (!deIntIsPow2(static_cast<int>(fragmentSize.width)) || !deIntIsPow2(static_cast<int>(fragmentSize.height)))
362 {
363 log << tcu::TestLog::Message << "fragmentSize should be power of 2" << tcu::TestLog::EndMessage;
364 someChecksFailed = true;
365 }
366
367 // Check that the width and height are less than the values in the maxFragmentSize limit
368 if ((fragmentSize.width > fragmentShadingRateProperties.maxFragmentSize.width) ||
369 (fragmentSize.height > fragmentShadingRateProperties.maxFragmentSize.height))
370 {
371 log << tcu::TestLog::Message
372 << "fragmentSize width and height are not less than the values in the maxFragmentSize"
373 << tcu::TestLog::EndMessage;
374 someChecksFailed = true;
375 }
376
377 if ((fragmentSize.width * fragmentSize.height) == 1)
378 {
379 // special case for fragmentSize {1, 1}
380 if (fsr.sampleCounts != ~0u)
381 {
382 log << tcu::TestLog::Message
383 << "implementations must support sampleCounts equal to ~0 for fragmentSize {1, 1}"
384 << tcu::TestLog::EndMessage;
385 someChecksFailed = true;
386 }
387 }
388 else
389 {
390 // get highest sample count value
391 uint32_t highestSampleCount = 0x80000000;
392 while (highestSampleCount)
393 {
394 if (fsr.sampleCounts & highestSampleCount)
395 break;
396 highestSampleCount >>= 1;
397 }
398
399 // Check that the highest sample count in sampleCounts is less than or equal to maxFragmentShadingRateRasterizationSamples limit
400 if (highestSampleCount >
401 static_cast<uint32_t>(fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples))
402 {
403 log << tcu::TestLog::Message
404 << "highest sample count value is not less than or equal to the "
405 "maxFragmentShadingRateRasterizationSamples limit"
406 << tcu::TestLog::EndMessage;
407 someChecksFailed = true;
408 }
409
410 // Check that the product of the width, height, and highest sample count value is less than the maxFragmentShadingRateCoverageSamples limit
411 if ((fragmentSize.width * fragmentSize.height * highestSampleCount) >
412 fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples)
413 {
414 log << tcu::TestLog::Message
415 << "product of the width, height, and highest sample count value is not less than the "
416 "maxFragmentShadingRateCoverageSamples limit"
417 << tcu::TestLog::EndMessage;
418 someChecksFailed = true;
419 }
420 }
421
422 // Check that the entries in the array are ordered first by largest to smallest width, then largest to smallest height
423 {
424 const uint32_t currentWidth = fragmentSize.width;
425 if (widthCheckPassed && (currentWidth > previousWidth))
426 {
427 log << tcu::TestLog::Message
428 << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries that are not ordered by largest to "
429 "smallest width"
430 << tcu::TestLog::EndMessage;
431 widthCheckPassed = false;
432 }
433
434 uint32_t currentHeight = fragmentSize.height;
435 if (heightCheckPassed)
436 {
437 // we can check order of height only for entries that have same width
438 if (currentWidth == previousWidth)
439 {
440 if (currentHeight > previousHeight)
441 {
442 log << tcu::TestLog::Message
443 << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same width but height "
444 "is not ordered by largest to smallest"
445 << tcu::TestLog::EndMessage;
446 heightCheckPassed = false;
447 }
448 }
449 else
450 currentHeight = std::numeric_limits<uint32_t>::max();
451 }
452
453 previousWidth = currentWidth;
454 previousHeight = currentHeight;
455 }
456
457 // Check that no two entries in the array have the same fragmentSize.width and fragmentSize.height value
458 {
459 uint32_t count = 0;
460 for (const auto &fsrB : fragmentShadingRateVect)
461 {
462 if ((fragmentSize.width == fsrB.fragmentSize.width) &&
463 (fragmentSize.height == fsrB.fragmentSize.height))
464 {
465 if (++count > 1)
466 {
467 log << tcu::TestLog::Message
468 << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same fragmentSize"
469 << tcu::TestLog::EndMessage;
470 someChecksFailed = true;
471 break;
472 }
473 }
474 }
475 }
476
477 // Check that 1x1, 1x2, 2x1, and 2x2 rates are supported with sample counts of 1 and 4
478 if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
479 (!(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) || !(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_4_BIT)))
480 {
481 log << tcu::TestLog::Message
482 << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample "
483 "counts not supporting 1 and 4"
484 << tcu::TestLog::EndMessage;
485 someChecksFailed = true;
486 }
487
488 // 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.
489 if (context.getDeviceProperties().limits.framebufferColorSampleCounts & vk::VK_SAMPLE_COUNT_2_BIT)
490 {
491 if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
492 !(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_2_BIT))
493 {
494 log << tcu::TestLog::Message
495 << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample "
496 "counts not supporting 2 while framebufferColorSampleCounts does"
497 << tcu::TestLog::EndMessage;
498 someChecksFailed = true;
499 }
500 }
501 }
502
503 if (someChecksFailed || !widthCheckPassed || !heightCheckPassed)
504 return tcu::TestStatus::fail("fail");
505
506 return tcu::TestStatus::pass("pass");
507 }
508
checkSupport(Context & context)509 void checkSupport(Context &context)
510 {
511 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
512 }
513
createMiscTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * parentGroup)514 void createMiscTests(tcu::TestContext &testCtx, tcu::TestCaseGroup *parentGroup)
515 {
516 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc"));
517
518 addFunctionCase(group.get(), "limits", checkSupport, testLimits);
519 addFunctionCase(group.get(), "shading_rates", checkSupport, testShadingRates);
520
521 createFragmentShadingRateMiscTests(group.get());
522
523 parentGroup->addChild(group.release());
524 }
525
createTests(tcu::TestCaseGroup * group,SharedGroupParams groupParams)526 void createTests(tcu::TestCaseGroup *group, SharedGroupParams groupParams)
527 {
528 tcu::TestContext &testCtx = group->getTestContext();
529
530 createBasicTests(testCtx, group, groupParams);
531
532 // attachmentFragmentShadingRate feature is tested with basic tests so there is no need to
533 // duplicating those tests for secondary command buffer;
534 // those tests are also not repeated for non monolithic pipelines
535 if (!groupParams->useSecondaryCmdBuffer &&
536 (groupParams->pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC))
537 createAttachmentRateTests(testCtx, group, groupParams);
538
539 // run pixel consistency tests and misc tests only with renderpass2 and monolithic pipeline
540 if (!groupParams->useDynamicRendering && !groupParams->useSecondaryCmdBuffer &&
541 (groupParams->pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC))
542 {
543 // there is no point in duplicating those tests for dynamic rendering
544 createMiscTests(testCtx, group);
545
546 // subpasses can't be translated to dynamic rendering
547 createPixelConsistencyTests(testCtx, group);
548 }
549 }
550
createPipelineConstructionTypePermutations(tcu::TestCaseGroup * parentGroup,SharedGroupParams baseGroupParams)551 void createPipelineConstructionTypePermutations(tcu::TestCaseGroup *parentGroup, SharedGroupParams baseGroupParams)
552 {
553 tcu::TestContext &testCtx = parentGroup->getTestContext();
554
555 auto constructGroupParams = [&baseGroupParams](vk::PipelineConstructionType pipelineConstructionType)
556 {
557 return SharedGroupParams(new GroupParams{
558 baseGroupParams->useDynamicRendering,
559 baseGroupParams->useSecondaryCmdBuffer,
560 baseGroupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass,
561 pipelineConstructionType,
562 });
563 };
564
565 typedef de::MovePtr<tcu::TestCaseGroup> TestGroupPtr;
566 // Monolithic pipeline tests
567 TestGroupPtr monolithic(createTestGroup(testCtx, "monolithic", createTests,
568 constructGroupParams(vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)));
569 parentGroup->addChild(monolithic.release());
570
571 #ifndef CTS_USES_VULKANSC
572 // Graphics pipeline library tests
573 TestGroupPtr pipelineLibrary(
574 createTestGroup(testCtx, "pipeline_library", createTests,
575 constructGroupParams(vk::PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)));
576 // Fast linked graphics pipeline library tests
577 TestGroupPtr fastLinkedLibrary(
578 createTestGroup(testCtx, "fast_linked_library", createTests,
579 constructGroupParams(vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY)));
580
581 parentGroup->addChild(pipelineLibrary.release());
582 parentGroup->addChild(fastLinkedLibrary.release());
583 #endif // CTS_USES_VULKANSC
584 }
585
586 #ifndef CTS_USES_VULKANSC
createDynamicRenderingPermutations(tcu::TestCaseGroup * parentGroup)587 void createDynamicRenderingPermutations(tcu::TestCaseGroup *parentGroup)
588 {
589 tcu::TestContext &testCtx = parentGroup->getTestContext();
590
591 auto constructGroupParams =
592 [](bool useSecondaryCmdBuffer, bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
593 {
594 return SharedGroupParams(new GroupParams{
595 true, // bool useDynamicRendering;
596 useSecondaryCmdBuffer, // bool useSecondaryCmdBuffer;
597 secondaryCmdBufferCompletelyContainsDynamicRenderpass, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
598 vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, // PipelineConstructionType pipelineConstructionType;
599 });
600 };
601
602 typedef de::MovePtr<tcu::TestCaseGroup> TestGroupPtr;
603 // Draw using Draw commands are recorded in primary command buffer
604 TestGroupPtr drPrimaryCmdBuffGroup(createTestGroup(
605 testCtx, "primary_cmd_buff", createPipelineConstructionTypePermutations, constructGroupParams(false, false)));
606 // Secondary command buffer doesn't include begin/endRendering
607 TestGroupPtr drPartialSecondaryCmdBuffGroup(
608 createTestGroup(testCtx, "partial_secondary_cmd_buff", createTests, constructGroupParams(true, false)));
609 // Secondary command buffer contains completely dynamic renderpass
610 TestGroupPtr drCompleteSecondaryCmdBuffGroup(
611 createTestGroup(testCtx, "complete_secondary_cmd_buff", createTests, constructGroupParams(true, true)));
612
613 parentGroup->addChild(drPrimaryCmdBuffGroup.release());
614 parentGroup->addChild(drPartialSecondaryCmdBuffGroup.release());
615 parentGroup->addChild(drCompleteSecondaryCmdBuffGroup.release());
616 }
617 #endif // CTS_USES_VULKANSC
618
619 } // namespace
620
createTests(tcu::TestContext & testCtx,const std::string & name)621 tcu::TestCaseGroup *createTests(tcu::TestContext &testCtx, const std::string &name)
622 {
623 // Fragment shading rate tests
624 de::MovePtr<tcu::TestCaseGroup> mainGroup(new tcu::TestCaseGroup(testCtx, name.c_str()));
625 // Draw using render pass object
626 de::MovePtr<tcu::TestCaseGroup> renderpass2Group(createTestGroup(
627 testCtx, "renderpass2", createPipelineConstructionTypePermutations,
628 SharedGroupParams(new GroupParams{
629 false, // bool useDynamicRendering;
630 false, // bool useSecondaryCmdBuffer;
631 false, // bool secondaryCmdBufferCompletelyContainsDynamicRenderpass;
632 vk::PipelineConstructionType(0) // placeholder // PipelineConstructionType pipelineConstructionType;
633 })));
634 mainGroup->addChild(renderpass2Group.release());
635
636 #ifndef CTS_USES_VULKANSC
637 de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup(
638 createTestGroup(testCtx, "dynamic_rendering", createDynamicRenderingPermutations));
639 mainGroup->addChild(dynamicRenderingGroup.release());
640 #endif // CTS_USES_VULKANSC
641
642 return mainGroup.release();
643 }
644
645 } // namespace FragmentShadingRate
646 } // namespace vkt
647