xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan coverage tests for extensions VK_KHR_display,
22  *        VK_KHR_get_display_properties2
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktWsiDisplayTests.hpp"
26 
27 #include "vktTestCase.hpp"
28 #include "vkStrUtil.hpp"
29 #include "vkPrograms.hpp"
30 #include "vkRef.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkWsiUtil.hpp"
33 
34 #include "tcuDefs.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuResultCollector.hpp"
37 
38 #include "deMemory.h"
39 #include "deSTLUtil.hpp"
40 #include "deStringUtil.hpp"
41 
42 #include <set>
43 #include <map>
44 #include <limits>
45 #include <sstream>
46 #include <stdexcept>
47 
48 namespace vkt
49 {
50 namespace wsi
51 {
52 using namespace vk;
53 using std::map;
54 using std::set;
55 using std::string;
56 using std::vector;
57 
58 #ifndef TCU_FAIL_STR
59 #define TCU_FAIL_STR(MSG) TCU_FAIL(string(MSG).c_str())
60 #endif
61 
62 enum DisplayIndexTest
63 {
64     DISPLAY_TEST_INDEX_START,
65     DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES,
66     DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES,
67     DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY,
68     DISPLAY_TEST_INDEX_GET_DISPLAY_MODE,
69     DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE,
70     DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES,
71     DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE,
72     DISPLAY_TEST_INDEX_SURFACE_COUNTERS,
73     DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2,
74     DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2,
75     DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2,
76     DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2,
77     DISPLAY_TEST_INDEX_LAST
78 };
79 
80 template <typename Type>
81 class BinaryCompare
82 {
83 public:
operator ()(const Type & a,const Type & b) const84     bool operator()(const Type &a, const Type &b) const
85     {
86         return deMemCmp(&a, &b, sizeof(Type)) < 0;
87     }
88 };
89 
90 typedef std::set<vk::VkDisplayKHR, BinaryCompare<vk::VkDisplayKHR>> DisplaySet;
91 typedef std::vector<vk::VkDisplayKHR> DisplayVector;
92 typedef std::vector<vk::VkDisplayModePropertiesKHR> DisplayModePropertiesVector;
93 typedef std::vector<vk::VkDisplayModeProperties2KHR> DisplayModeProperties2Vector;
94 
95 const uint32_t DEUINT32_MAX = std::numeric_limits<uint32_t>::max();
96 
97 const uint32_t RECOGNIZED_SURFACE_TRANSFORM_FLAGS =
98     vk::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | vk::VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
99     vk::VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR | vk::VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
100     vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR | vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
101     vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR |
102     vk::VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR | vk::VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
103 
104 const uint32_t RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS =
105     VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR | VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR |
106     VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR | VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR;
107 enum DisplayMaxTestedConsts
108 {
109     MAX_TESTED_DISPLAY_COUNT = 16,
110     MAX_TESTED_PLANE_COUNT   = 16,
111 };
112 
113 /*--------------------------------------------------------------------*//*!
114  * \brief Return Vulkan result name or code as std::string.
115  *
116  * \param result Vulkan code to convert to string
117  * \return Vulkun result code name or code number as std::string
118  *//*--------------------------------------------------------------------*/
getResultAsString(vk::VkResult result)119 std::string getResultAsString(vk::VkResult result)
120 {
121     const char *resultAsChar = vk::getResultName(result);
122 
123     if (resultAsChar != DE_NULL)
124         return std::string(resultAsChar);
125     else
126         return de::toString(result);
127 }
128 
129 /*--------------------------------------------------------------------*//*!
130  * \brief Moves test index to next test skipping middle tests.
131  *
132  * Gets first 3 tests and last 3 tests on long sequences.
133  * After test number 2 moves index value to endIndex - 3.
134  * Shortens the number of tests executed by skipping middle tests.
135  *
136  * Example:
137  * for (i=0; i<endIndex; nextTestNumber(i, endIndex))
138  * with endIndex = 4 generates 0,1,2,3
139  * with endIndex = 9 generates 0,1,2,6,7,8
140  *
141  * \param index    Current iterator value
142  * \param endIndex First number out of iteration sequence
143  * \return new iterator value
144  *//*--------------------------------------------------------------------*/
nextTestNumber(uint32_t index,uint32_t endIndex)145 uint32_t nextTestNumber(uint32_t index, uint32_t endIndex)
146 {
147     uint32_t result;
148 
149     if (endIndex > 6 && index == 2)
150         result = endIndex - 3;
151     else
152         result = index + 1;
153 
154     return result;
155 }
156 
157 /*--------------------------------------------------------------------*//*!
158  * \brief Vulkan VK_KHR_display extensions coverage tests
159  *//*--------------------------------------------------------------------*/
160 class DisplayCoverageTestInstance : public TestInstance
161 {
162 public:
163     DisplayCoverageTestInstance(Context &context, const DisplayIndexTest testId);
164 
165 private:
166     typedef void (DisplayCoverageTestInstance::*EachSurfaceFunctionPtr)(VkSurfaceKHR &surface,
167                                                                         VkDisplayModePropertiesKHR &modeProperties);
168 
169     bool getDisplays(DisplayVector &displays);
170     bool getDisplaysForPlane(uint32_t plane, DisplayVector &displays);
171     bool getDisplayModeProperties(VkDisplayKHR display, DisplayModePropertiesVector &modeProperties);
172 
173     bool getDisplays2(DisplayVector &displays);
174     bool getDisplayModeProperties2(VkDisplayKHR display, DisplayModeProperties2Vector &modeProperties);
175 
176     void validateDisplayProperties(tcu::ResultCollector &results, const VkDisplayPropertiesKHR &toValidate,
177                                    const VkDisplayPropertiesKHR &nonUpdated);
178 
179     void validateDisplayPlaneProperties(tcu::ResultCollector &results, const VkDisplayPlanePropertiesKHR &toValidate,
180                                         const VkDisplayPlanePropertiesKHR &nonUpdated, DisplaySet &displaySet);
181 
182     void validateDisplayPlaneCapabilities(tcu::ResultCollector &results,
183                                           const VkDisplayPlaneCapabilitiesKHR &toValidate,
184                                           const VkDisplayPlaneCapabilitiesKHR &nonUpdated);
185 
186     void validateDisplayModeProperties(tcu::ResultCollector &results, const VkDisplayModePropertiesKHR &toValidate,
187                                        const VkDisplayModePropertiesKHR &nonUpdated);
188 
189     // VK_KHR_display extension tests
190     tcu::TestStatus testGetPhysicalDeviceDisplayPropertiesKHR(void);
191     tcu::TestStatus testGetPhysicalDeviceDisplayPlanePropertiesKHR(void);
192     tcu::TestStatus testGetDisplayPlaneSupportedDisplaysKHR(void);
193     tcu::TestStatus testGetDisplayModePropertiesKHR(void);
194     tcu::TestStatus testCreateDisplayModeKHR(void);
195     tcu::TestStatus testGetDisplayPlaneCapabilitiesKHR(void);
196 
197     enum SurfaceTestKind
198     {
199         SURFACE_CREATE = 0,
200         SURFACE_COUNTERS,
201         SURFACE_TEST_KIND_MAX_ENUM
202     };
203 
204     tcu::TestStatus testDisplaySurface(SurfaceTestKind testKind);
205 
206     // VK_KHR_get_display_properties2 extension tests
207     tcu::TestStatus testGetPhysicalDeviceDisplayProperties2KHR(void);
208     tcu::TestStatus testGetPhysicalDeviceDisplayPlaneProperties2KHR(void);
209     tcu::TestStatus testGetDisplayModeProperties2KHR(void);
210     tcu::TestStatus testGetDisplayPlaneCapabilities2KHR(void);
211 
212     tcu::TestStatus iterate(void);
213 
214     void testCreateSharedSwapchainsKHRforSurface(VkSurfaceKHR &surface, VkDisplayModePropertiesKHR &modeProperties);
215 
216     const InstanceInterface &m_vki;
217     const DeviceInterface &m_vkd;
218     tcu::TestLog &m_log;
219     const VkPhysicalDevice m_physicalDevice;
220     const DisplayIndexTest m_testId;
221 };
222 
223 /*--------------------------------------------------------------------*//*!
224  * \brief DisplayCoverageTestInstance constructor
225  *
226  * Initializes DisplayCoverageTestInstance object
227  *
228  * \param context    Context object
229  * \param parameters Test parameters structure
230  *//*--------------------------------------------------------------------*/
DisplayCoverageTestInstance(Context & context,const DisplayIndexTest testId)231 DisplayCoverageTestInstance::DisplayCoverageTestInstance(Context &context, const DisplayIndexTest testId)
232     : TestInstance(context)
233     , m_vki(m_context.getInstanceInterface())
234     , m_vkd(m_context.getDeviceInterface())
235     , m_log(m_context.getTestContext().getLog())
236     , m_physicalDevice(m_context.getPhysicalDevice())
237     , m_testId(testId)
238 {
239     const std::string extensionName("VK_KHR_display");
240 
241     if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), extensionName))
242         TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
243 
244     switch (m_testId)
245     {
246     case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:
247     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:
248     case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:
249     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:
250     {
251         const std::string extensionNameAddition("VK_KHR_get_display_properties2");
252 
253         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(),
254                           extensionNameAddition))
255             TCU_THROW(NotSupportedError, std::string(extensionNameAddition + " is not supported").c_str());
256 
257         break;
258     }
259 
260     default:
261     {
262         break;
263     }
264     }
265 }
266 
267 /*--------------------------------------------------------------------*//*!
268  * \brief Step forward test execution
269  *
270  * \return true if application should call iterate() again and false
271  *         if test execution session is complete.
272  *//*--------------------------------------------------------------------*/
iterate(void)273 tcu::TestStatus DisplayCoverageTestInstance::iterate(void)
274 {
275     switch (m_testId)
276     {
277     case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES:
278         return testGetPhysicalDeviceDisplayPropertiesKHR();
279     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES:
280         return testGetPhysicalDeviceDisplayPlanePropertiesKHR();
281     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY:
282         return testGetDisplayPlaneSupportedDisplaysKHR();
283     case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE:
284         return testGetDisplayModePropertiesKHR();
285     case DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE:
286         return testCreateDisplayModeKHR();
287     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES:
288         return testGetDisplayPlaneCapabilitiesKHR();
289     case DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE:
290         return testDisplaySurface(SURFACE_CREATE);
291     case DISPLAY_TEST_INDEX_SURFACE_COUNTERS:
292         return testDisplaySurface(SURFACE_COUNTERS);
293     case DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2:
294         return testGetPhysicalDeviceDisplayProperties2KHR();
295     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2:
296         return testGetPhysicalDeviceDisplayPlaneProperties2KHR();
297     case DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2:
298         return testGetDisplayModeProperties2KHR();
299     case DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2:
300         return testGetDisplayPlaneCapabilities2KHR();
301     default:
302     {
303         DE_FATAL("Impossible");
304     }
305     }
306 
307     TCU_FAIL("Invalid test identifier");
308 }
309 
310 /*--------------------------------------------------------------------*//*!
311  * \brief Fills vector with available displays. Clears passed vector at start.
312  *
313  * \param displays The vector filled with display handles
314  * \return true on success, false on error
315  *//*--------------------------------------------------------------------*/
getDisplays(DisplayVector & displays)316 bool DisplayCoverageTestInstance::getDisplays(DisplayVector &displays)
317 {
318     uint32_t countReported  = 0u;
319     uint32_t countRetrieved = 0u;
320     std::vector<VkDisplayPropertiesKHR> displaysProps;
321     VkResult result;
322 
323     displays.clear();
324 
325     result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(m_physicalDevice, // VkPhysicalDevice            physicalDevice
326                                                          &countReported,   // uint32_t*                pPropertyCount
327                                                          DE_NULL);         // VkDisplayPropertiesKHR*    pProperties
328 
329     if (result != VK_SUCCESS)
330     {
331         m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with "
332               << getResultAsString(result) << " reported items count " << countReported << tcu::TestLog::EndMessage;
333 
334         return false;
335     }
336 
337     if (!countReported)
338         TCU_THROW(NotSupportedError, "No displays reported");
339 
340     displaysProps.resize(countReported);
341 
342     countRetrieved = countReported;
343 
344     result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(m_physicalDevice, // VkPhysicalDevice            physicalDevice
345                                                          &countRetrieved,  // uint32_t*                pPropertyCount
346                                                          &displaysProps[0]); // VkDisplayPropertiesKHR*    pProperties
347 
348     if (result != VK_SUCCESS || countRetrieved > countReported)
349     {
350         m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayPropertiesKHR failed with "
351               << getResultAsString(result) << " reported items count " << countReported << " retrieved items count "
352               << countRetrieved << tcu::TestLog::EndMessage;
353 
354         return false;
355     }
356 
357     displays.reserve(countRetrieved);
358 
359     for (uint32_t displayIndex = 0; displayIndex < countRetrieved; displayIndex++)
360     {
361         const VkDisplayKHR display = displaysProps[displayIndex].display;
362 
363         if (display == DE_NULL)
364         {
365             displays.clear();
366 
367             return false;
368         }
369 
370         displays.push_back(display);
371     }
372 
373     return true;
374 }
375 
376 /*--------------------------------------------------------------------*//*!
377  * \brief Fills vector with available displays for plane specified.
378  *
379  * Clears passed vector at start and on error.
380  *
381  * \param plane        The plane to get displays for
382  * \param displays    The vector filled with display handles
383  * \return true on success, false on error
384  *//*--------------------------------------------------------------------*/
getDisplaysForPlane(uint32_t plane,DisplayVector & displays)385 bool DisplayCoverageTestInstance::getDisplaysForPlane(uint32_t plane, DisplayVector &displays)
386 {
387     uint32_t countReported  = 0u;
388     uint32_t countRetrieved = 0u;
389     VkResult result;
390 
391     displays.clear();
392 
393     result = m_vki.getDisplayPlaneSupportedDisplaysKHR(m_physicalDevice, // VkPhysicalDevice    physicalDevice
394                                                        plane,            // uint32_t            planeIndex
395                                                        &countReported,   // uint32_t*        pDisplayCount
396                                                        DE_NULL);         // VkDisplayKHR*    pDisplays
397 
398     if (result != VK_SUCCESS)
399     {
400         m_log << tcu::TestLog::Message << "vkGetDisplayPlaneSupportedDisplaysKHR failed with "
401               << getResultAsString(result) << " for plane " << plane << " reported items count " << countReported
402               << tcu::TestLog::EndMessage;
403 
404         return false;
405     }
406 
407     displays.resize(countReported);
408 
409     countRetrieved = countReported;
410 
411     result = m_vki.getDisplayPlaneSupportedDisplaysKHR(m_physicalDevice, // VkPhysicalDevice    physicalDevice
412                                                        plane,            // uint32_t            planeIndex
413                                                        &countRetrieved,  // uint32_t*        pDisplayCount
414                                                        &displays[0]);    // VkDisplayKHR*    pDisplays
415 
416     if (result != VK_SUCCESS || countRetrieved > countReported)
417     {
418         m_log << tcu::TestLog::Message << "vkGetDisplayPlaneSupportedDisplaysKHR failed with "
419               << getResultAsString(result) << " for plane " << plane << " reported items count " << countReported
420               << " retrieved items count " << countRetrieved << tcu::TestLog::EndMessage;
421 
422         displays.clear();
423 
424         return false;
425     }
426 
427     if (countRetrieved < countReported)
428         displays.resize(countRetrieved);
429 
430     return true;
431 }
432 
433 /*--------------------------------------------------------------------*//*!
434  * \brief Fills vector with available modes properties for display specified.
435  *
436  * Clears passed vector at start and on error.
437  *
438  * \param display    The display to get modes for
439  * \param modes        The vector filled with display mode properties structures
440  * \return true on success, false on error
441  *//*--------------------------------------------------------------------*/
getDisplayModeProperties(VkDisplayKHR display,DisplayModePropertiesVector & modeProperties)442 bool DisplayCoverageTestInstance::getDisplayModeProperties(VkDisplayKHR display,
443                                                            DisplayModePropertiesVector &modeProperties)
444 {
445     uint32_t countReported  = 0u;
446     uint32_t countRetrieved = 0u;
447     VkResult result;
448 
449     modeProperties.clear();
450 
451     result = m_vki.getDisplayModePropertiesKHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
452                                                display,          // VkDisplayKHR                    display
453                                                &countReported,   // uint32_t*                    pPropertyCount
454                                                DE_NULL);         // VkDisplayModePropertiesKHR*    pProperties
455 
456     if (result != VK_SUCCESS)
457     {
458         m_log << tcu::TestLog::Message << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
459               << " for display " << display << " reported items count " << countReported << tcu::TestLog::EndMessage;
460 
461         return false;
462     }
463 
464     modeProperties.resize(countReported);
465 
466     countRetrieved = countReported;
467 
468     result = m_vki.getDisplayModePropertiesKHR(m_physicalDevice,    // VkPhysicalDevice                physicalDevice
469                                                display,             // VkDisplayKHR                    display
470                                                &countRetrieved,     // uint32_t*                    pPropertyCount
471                                                &modeProperties[0]); // VkDisplayModePropertiesKHR*    pProperties
472 
473     if (result != VK_SUCCESS || countRetrieved > countReported)
474     {
475         m_log << tcu::TestLog::Message << "vkGetDisplayModePropertiesKHR failed with " << getResultAsString(result)
476               << " for display " << display << " reported items count " << countReported << " retrieved items count "
477               << countReported << tcu::TestLog::EndMessage;
478 
479         modeProperties.clear();
480 
481         return false;
482     }
483 
484     if (countRetrieved < countReported)
485         modeProperties.resize(countRetrieved);
486 
487     return true;
488 }
489 
490 /*--------------------------------------------------------------------*//*!
491  * \brief Fills vector with available displays. Clears passed vector at start.
492  *
493  * Uses VK_KHR_get_display_properties2 extension API.
494  * Clears passed vector at start.
495  *
496  * \param displays The vector filled with display handles
497  * \return true on success, false on error
498  *//*--------------------------------------------------------------------*/
getDisplays2(DisplayVector & displays)499 bool DisplayCoverageTestInstance::getDisplays2(DisplayVector &displays)
500 {
501     uint32_t countReported                         = 0u;
502     uint32_t countRetrieved                        = 0u;
503     const VkDisplayPropertiesKHR displayProperties = {
504         DE_NULL,  // VkDisplayKHR                    display
505         DE_NULL,  // const char*                    displayName
506         {0, 0},   // VkExtent2D                    physicalDimensions
507         {0, 0},   // VkExtent2D                    physicalResolution
508         0,        // VkSurfaceTransformFlagsKHR    supportedTransforms
509         VK_FALSE, // VkBool32                        planeReorderPossible
510         VK_FALSE  // VkBool32                        persistentContent
511     };
512     const VkDisplayProperties2KHR displayProperties2 = {
513         VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR, // VkStructureType            sType
514         DE_NULL,                                    // void*                    pNext
515         displayProperties                           // VkDisplayPropertiesKHR    displayProperties
516     };
517 
518     std::vector<VkDisplayProperties2KHR> displaysProps;
519     VkResult result;
520 
521     displays.clear();
522 
523     result =
524         m_vki.getPhysicalDeviceDisplayProperties2KHR(m_physicalDevice, // VkPhysicalDevice            physicalDevice
525                                                      &countReported,   // uint32_t*                pPropertyCount
526                                                      DE_NULL);         // VkDisplayProperties2KHR*    pProperties
527 
528     if (result != VK_SUCCESS)
529     {
530         m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayProperties2KHR failed with "
531               << getResultAsString(result) << " reported items count " << countReported << tcu::TestLog::EndMessage;
532 
533         return false;
534     }
535 
536     if (!countReported)
537         TCU_THROW(NotSupportedError, "No displays reported");
538 
539     displaysProps.resize(countReported, displayProperties2);
540 
541     countRetrieved = countReported;
542 
543     result =
544         m_vki.getPhysicalDeviceDisplayProperties2KHR(m_physicalDevice,   // VkPhysicalDevice            physicalDevice
545                                                      &countRetrieved,    // uint32_t*                pPropertyCount
546                                                      &displaysProps[0]); // VkDisplayPropertiesKHR*    pProperties
547 
548     if (result != VK_SUCCESS || countRetrieved > countReported)
549     {
550         m_log << tcu::TestLog::Message << "vkGetPhysicalDeviceDisplayProperties2KHR failed with "
551               << getResultAsString(result) << " reported items count " << countReported << " retrieved items count "
552               << countRetrieved << tcu::TestLog::EndMessage;
553 
554         return false;
555     }
556 
557     displays.reserve(countRetrieved);
558 
559     for (uint32_t displayIndex = 0; displayIndex < countRetrieved; displayIndex++)
560     {
561         const VkDisplayKHR display = displaysProps[displayIndex].displayProperties.display;
562 
563         if (display == DE_NULL)
564         {
565             displays.clear();
566 
567             return false;
568         }
569 
570         displays.push_back(display);
571     }
572 
573     return true;
574 }
575 
576 /*--------------------------------------------------------------------*//*!
577  * \brief Fills vector with available modes properties for display specified.
578  *
579  * Uses VK_KHR_get_display_properties2 extension API.
580  * Clears passed vector at start and on error.
581  *
582  * \param display    The display to get modes for
583  * \param modes        The vector filled with display mode properties structures
584  * \return true on success, false on error
585  *//*--------------------------------------------------------------------*/
getDisplayModeProperties2(VkDisplayKHR display,DisplayModeProperties2Vector & modeProperties)586 bool DisplayCoverageTestInstance::getDisplayModeProperties2(VkDisplayKHR display,
587                                                             DisplayModeProperties2Vector &modeProperties)
588 {
589     uint32_t countReported                                   = 0u;
590     uint32_t countRetrieved                                  = 0u;
591     const VkDisplayModePropertiesKHR displayModeProperties   = {DE_NULL, // VkDisplayModeKHR                displayMode
592                                                                 {
593                                                                   // VkDisplayModeParametersKHR    parameters
594                                                                   {0, 0}, // VkExtent2D                    visibleRegion
595                                                                   0 // uint32_t                        refreshRate
596                                                               }};
597     const VkDisplayModeProperties2KHR displayModeProperties2 = {
598         VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR, // VkStructureType                sType
599         DE_NULL,                                         // void*                        pNext
600         displayModeProperties                            // VkDisplayModePropertiesKHR    displayModeProperties
601     };
602     VkResult result;
603 
604     modeProperties.clear();
605 
606     result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
607                                                 display,          // VkDisplayKHR                    display
608                                                 &countReported,   // uint32_t*                    pPropertyCount
609                                                 DE_NULL);         // VkDisplayModeProperties2KHR*    pProperties
610 
611     if (result != VK_SUCCESS)
612     {
613         m_log << tcu::TestLog::Message << "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
614               << " for display " << display << " reported items count " << countReported << tcu::TestLog::EndMessage;
615 
616         return false;
617     }
618 
619     modeProperties.resize(countReported, displayModeProperties2);
620 
621     countRetrieved = countReported;
622 
623     result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice,    // VkPhysicalDevice                physicalDevice
624                                                 display,             // VkDisplayKHR                    display
625                                                 &countRetrieved,     // uint32_t*                    pPropertyCount
626                                                 &modeProperties[0]); // VkDisplayModeProperties2KHR*    pProperties
627 
628     if (result != VK_SUCCESS || countRetrieved > countReported)
629     {
630         m_log << tcu::TestLog::Message << "vkGetDisplayModeProperties2KHR failed with " << getResultAsString(result)
631               << " for display " << display << " reported items count " << countReported << " retrieved items count "
632               << countReported << tcu::TestLog::EndMessage;
633 
634         modeProperties.clear();
635 
636         return false;
637     }
638 
639     if (countRetrieved < countReported)
640         modeProperties.resize(countRetrieved);
641 
642     return true;
643 }
644 
645 /*--------------------------------------------------------------------*//*!
646  * \brief Validate display properties and report failures
647  *        into results collector
648  *
649  * \param results        Results collector
650  * \param toValidate    Display properties to validate
651  * \param nonUpdated    Display properties to compare with
652  *//*--------------------------------------------------------------------*/
validateDisplayProperties(tcu::ResultCollector & results,const VkDisplayPropertiesKHR & toValidate,const VkDisplayPropertiesKHR & nonUpdated)653 void DisplayCoverageTestInstance::validateDisplayProperties(tcu::ResultCollector &results,
654                                                             const VkDisplayPropertiesKHR &toValidate,
655                                                             const VkDisplayPropertiesKHR &nonUpdated)
656 {
657     results.check(toValidate.display != nonUpdated.display, "Invalid display handle");
658 
659     results.check(toValidate.planeReorderPossible == VK_TRUE || toValidate.planeReorderPossible == VK_FALSE,
660                   "planeReorderPossible neither VK_TRUE, nor VK_FALSE");
661 
662     results.check(toValidate.persistentContent == VK_TRUE || toValidate.persistentContent == VK_FALSE,
663                   "persistentContent neither VK_TRUE, nor VK_FALSE");
664 
665     results.check((toValidate.supportedTransforms & nonUpdated.supportedTransforms) == 0,
666                   "supportedTransforms contains unrecognized flags");
667 
668     // Outside specification, but resolution 0x0 pixels will break many applications
669     results.check(toValidate.physicalResolution.height != 0, "physicalResolution.height cannot be zero");
670 
671     // Outside specification, but resolution 0x0 pixels will break many applications
672     results.check(toValidate.physicalResolution.width != 0, "physicalResolution.width cannot be zero");
673 }
674 
675 /*--------------------------------------------------------------------*//*!
676  * \brief Validates display plane properties and report failures
677  *        into results collector
678  *
679  * \param results        Results collector
680  * \param toValidate    Display plane properties to validate
681  * \param nonUpdated    Display plane properties to compare with
682  * \param displaySet    Set of valid display handles
683  *//*--------------------------------------------------------------------*/
validateDisplayPlaneProperties(tcu::ResultCollector & results,const VkDisplayPlanePropertiesKHR & toValidate,const VkDisplayPlanePropertiesKHR & nonUpdated,DisplaySet & displaySet)684 void DisplayCoverageTestInstance::validateDisplayPlaneProperties(tcu::ResultCollector &results,
685                                                                  const VkDisplayPlanePropertiesKHR &toValidate,
686                                                                  const VkDisplayPlanePropertiesKHR &nonUpdated,
687                                                                  DisplaySet &displaySet)
688 {
689     const VkDisplayKHR currentDisplay = toValidate.currentDisplay;
690 
691     results.check(toValidate.currentStackIndex < nonUpdated.currentStackIndex,
692                   "CurrentStackIndex must be less than the number of planes reported " +
693                       de::toString(nonUpdated.currentStackIndex));
694 
695     results.check(currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
696                   "Plane bound to invalid handle " + de::toString(toValidate.currentDisplay));
697 }
698 
699 /*--------------------------------------------------------------------*//*!
700  * \brief Validate display plane capabilities and report failures
701  *        into results collector
702  *
703  * \param results        Results collector
704  * \param toValidate    Display plane capabilities to validate
705  * \param nonUpdated    Display plane capabilities to compare with
706  *//*--------------------------------------------------------------------*/
validateDisplayPlaneCapabilities(tcu::ResultCollector & results,const VkDisplayPlaneCapabilitiesKHR & toValidate,const VkDisplayPlaneCapabilitiesKHR & nonUpdated)707 void DisplayCoverageTestInstance::validateDisplayPlaneCapabilities(tcu::ResultCollector &results,
708                                                                    const VkDisplayPlaneCapabilitiesKHR &toValidate,
709                                                                    const VkDisplayPlaneCapabilitiesKHR &nonUpdated)
710 {
711     results.check((toValidate.supportedAlpha & nonUpdated.supportedAlpha) == 0,
712                   "supportedAlpha contains unrecognized value");
713 
714     results.check(toValidate.minSrcPosition.x >= 0, "minSrcPosition.x >= 0");
715 
716     results.check(toValidate.minSrcPosition.y >= 0, "minSrcPosition.y >= 0");
717 
718     results.check(toValidate.maxSrcPosition.x >= 0, "maxSrcPosition.x >= 0");
719 
720     results.check(toValidate.maxSrcPosition.y >= 0, "maxSrcPosition.y >= 0");
721 
722     results.check(toValidate.minSrcPosition.x <= toValidate.maxSrcPosition.x, "minSrcPosition.x <= maxSrcPosition.x");
723 
724     results.check(toValidate.minSrcPosition.y <= toValidate.maxSrcPosition.y, "minSrcPosition.y <= maxSrcPosition.y");
725 
726     results.check(toValidate.minDstPosition.x <= toValidate.maxDstPosition.x, "minDstPosition.x <= maxDstPosition.x");
727 
728     results.check(toValidate.minDstPosition.y <= toValidate.maxDstPosition.y, "minDstPosition.y <= maxDstPosition.y");
729 
730     results.check(toValidate.minSrcExtent.width <= toValidate.maxSrcExtent.width,
731                   "minSrcExtent.width <= maxSrcExtent.width");
732 
733     results.check(toValidate.minSrcExtent.height <= toValidate.maxSrcExtent.height,
734                   "minSrcExtent.height <= maxSrcExtent.height");
735 
736     results.check(toValidate.minDstExtent.width <= toValidate.maxDstExtent.width,
737                   "minDstExtent.width <= maxDstExtent.width");
738 
739     results.check(toValidate.minDstExtent.height <= toValidate.maxDstExtent.height,
740                   "minDstExtent.height <= maxDstExtent.height");
741 }
742 
743 /*--------------------------------------------------------------------*//*!
744  * \brief Validate display mode properties and report failures
745  *        into results collector
746  *
747  * \param results        Results collector
748  * \param toValidate    Display mode properties to validate
749  * \param nonUpdated    Display mode properties to compare with
750  *//*--------------------------------------------------------------------*/
validateDisplayModeProperties(tcu::ResultCollector & results,const VkDisplayModePropertiesKHR & toValidate,const VkDisplayModePropertiesKHR & nonUpdated)751 void DisplayCoverageTestInstance::validateDisplayModeProperties(tcu::ResultCollector &results,
752                                                                 const VkDisplayModePropertiesKHR &toValidate,
753                                                                 const VkDisplayModePropertiesKHR &nonUpdated)
754 {
755     results.check(toValidate.displayMode != nonUpdated.displayMode, "Invalid mode display handle reported");
756 }
757 
758 /*--------------------------------------------------------------------*//*!
759  * \brief Display enumeration coverage test
760  *
761  * Throws ResourceError exception in case no displays available.
762  * Throws an exception on fail.
763  *
764  * \return tcu::TestStatus::pass on success
765  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPropertiesKHR(void)766 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPropertiesKHR(void)
767 {
768     uint32_t displayCountReported = 0u;
769     uint32_t displayCountToTest   = 0u;
770     tcu::ResultCollector results(m_log);
771     VkResult result;
772 
773     result =
774         m_vki.getPhysicalDeviceDisplayPropertiesKHR(m_physicalDevice,      // VkPhysicalDevice            physicalDevice
775                                                     &displayCountReported, // uint32_t*                pPropertyCount
776                                                     DE_NULL);              // VkDisplayPropertiesKHR*    pProperties
777 
778     if (result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY &&
779         result != VK_ERROR_OUT_OF_DEVICE_MEMORY)
780     {
781         TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
782     }
783 
784     if (result != VK_SUCCESS)
785         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
786 
787     if (displayCountReported == 0)
788         TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());
789 
790     displayCountToTest = displayCountReported;
791     if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
792     {
793         m_log << tcu::TestLog::Message << "Number of displays reported is too high " << displayCountReported
794               << ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT << tcu::TestLog::EndMessage;
795 
796         displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
797     }
798 
799     // Test the call correctly writes data in various size arrays
800     for (uint32_t displayCountRequested = 0; displayCountRequested < displayCountToTest + 2; displayCountRequested++)
801     {
802         const uint32_t displayCountExpected              = std::min(displayCountRequested, displayCountReported);
803         const VkDisplayPropertiesKHR invalidDisplayProps = {
804             // Most values are set to fail the test to make sure driver updates these
805             DE_NULL,                             // VkDisplayKHR display;
806             DE_NULL,                             // const char* displayName;
807             {0, 0},                              // VkExtent2D physicalDimensions;
808             {0, 0},                              // VkExtent2D physicalResolution;
809             ~RECOGNIZED_SURFACE_TRANSFORM_FLAGS, // VkSurfaceTransformFlagsKHR supportedTransforms;
810             (vk::VkBool32)(VK_TRUE + 1),         // VkBool32 planeReorderPossible;
811             (vk::VkBool32)(VK_TRUE + 1)          // VkBool32 persistentContent;
812         };
813         const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11);
814         const uint32_t canaryItemCount   = 1;
815         std::vector<VkDisplayPropertiesKHR> displaysProps(displayCountRequested + canaryItemCount, invalidDisplayProps);
816         uint32_t displayCountRetrieved = displayCountRequested;
817         DisplaySet displaySet;
818 
819         displaysProps[displayCountExpected].display = canaryDisplay;
820 
821         result = m_vki.getPhysicalDeviceDisplayPropertiesKHR(
822             m_physicalDevice,       // VkPhysicalDevice            physicalDevice
823             &displayCountRetrieved, // uint32_t*                pPropertyCount
824             &displaysProps[0]);     // VkDisplayPropertiesKHR*    pProperties
825 
826         // Check amount of data written equals to expected
827         if (displayCountRetrieved != displayCountExpected)
828             TCU_FAIL_STR(string("displayCountRetrieved != displayCountExpected, ") +
829                          de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
830 
831         if (displayCountRequested >= displayCountReported)
832         {
833             if (result != VK_SUCCESS)
834                 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
835         }
836         else
837         {
838             if (result != VK_INCOMPLETE)
839                 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
840         }
841 
842         // Check the driver has written something
843         for (uint32_t displayIndex = 0; displayIndex < displayCountRetrieved; displayIndex++)
844         {
845             displaySet.insert(displaysProps[displayIndex].display);
846 
847             results.check(displaysProps[displayIndex].display != invalidDisplayProps.display,
848                           "Invalid display handle for display number " + de::toString(displayIndex));
849 
850             results.check(displaysProps[displayIndex].planeReorderPossible == VK_TRUE ||
851                               displaysProps[displayIndex].planeReorderPossible == VK_FALSE,
852                           "planeReorderPossible neither VK_TRUE, nor VK_FALSE");
853 
854             results.check(displaysProps[displayIndex].persistentContent == VK_TRUE ||
855                               displaysProps[displayIndex].persistentContent == VK_FALSE,
856                           "persistentContent neither VK_TRUE, nor VK_FALSE");
857 
858             results.check((displaysProps[displayIndex].supportedTransforms & invalidDisplayProps.supportedTransforms) ==
859                               0,
860                           "supportedTransforms contains unrecognized flags");
861 
862             // Outside specification, but resolution 0x0 pixels will break many applications
863             results.check(displaysProps[displayIndex].physicalResolution.height != 0,
864                           "physicalResolution.height cannot be zero");
865 
866             // Outside specification, but resolution 0x0 pixels will break many applications
867             results.check(displaysProps[displayIndex].physicalResolution.width != 0,
868                           "physicalResolution.width cannot be zero");
869 
870             if (results.getResult() != QP_TEST_RESULT_PASS)
871             {
872                 m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for display "
873                       << displayIndex << " with properties " << displaysProps[displayIndex]
874                       << " invalid display properties are " << invalidDisplayProps << tcu::TestLog::EndMessage;
875 
876                 TCU_FAIL_STR(results.getMessage());
877             }
878         }
879 
880         // Check the driver has not written more than requested
881         if (displaysProps[displayCountExpected].display != canaryDisplay)
882             TCU_FAIL("Memory damage detected: driver has written more than expected");
883 
884         // Check display handle uniqueness
885         if (displaySet.size() != displayCountRetrieved)
886             TCU_FAIL("Display handle duplication detected");
887     }
888 
889     return tcu::TestStatus::pass("pass");
890 }
891 
892 /*--------------------------------------------------------------------*//*!
893  * \brief Plane enumeration coverage test
894  *
895  * Throws an exception on fail.
896  *
897  * \return tcu::TestStatus::pass on success
898  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPlanePropertiesKHR(void)899 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlanePropertiesKHR(void)
900 {
901     DisplayVector displaysVector;
902     DisplaySet displaySet;
903     uint32_t planeCountReported = 0u;
904     uint32_t planeCountTested   = 0u;
905     tcu::ResultCollector results(m_log);
906     VkResult result;
907 
908     // Create a list of displays available
909     if (!getDisplays(displaysVector))
910         TCU_FAIL("Failed to retrieve displays");
911 
912     if (displaysVector.empty())
913         TCU_THROW(NotSupportedError, "No displays reported");
914 
915     displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
916 
917     // Get planes to test
918     result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
919         m_physicalDevice,    // VkPhysicalDevice                physicalDevice
920         &planeCountReported, // uint32_t*                    pPropertyCount
921         DE_NULL);            // VkDisplayPlanePropertiesKHR*    pProperties
922 
923     if (result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY &&
924         result != VK_ERROR_OUT_OF_DEVICE_MEMORY)
925     {
926         TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
927     }
928 
929     if (result != VK_SUCCESS)
930         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
931 
932     if (planeCountReported == 0)
933         TCU_THROW(ResourceError, "Cannot perform test: no planes found");
934 
935     planeCountTested = planeCountReported;
936     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
937     {
938         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
939               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
940 
941         planeCountTested = MAX_TESTED_PLANE_COUNT;
942     }
943 
944     // Test the call correctly writes data in various size arrays
945     for (uint32_t planeCountRequested = 0; planeCountRequested < planeCountTested + 2; planeCountRequested++)
946     {
947         const uint32_t planeCountExpected                   = std::min(planeCountRequested, planeCountReported);
948         const VkDisplayPlanePropertiesKHR invalidPlaneProps = {
949             // Most values are set to fail the test to make sure driver updates these
950             DE_NULL,     // VkDisplayKHR    currentDisplay
951             DEUINT32_MAX // uint32_t        currentStackIndex
952         };
953         const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11);
954         const uint32_t canaryItemCount   = 1;
955         std::vector<VkDisplayPlanePropertiesKHR> planeProps(planeCountRequested + canaryItemCount, invalidPlaneProps);
956         uint32_t planeCountRetrieved = planeCountRequested;
957 
958         planeProps[planeCountExpected].currentDisplay = canaryDisplay;
959 
960         result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
961             m_physicalDevice,     // VkPhysicalDevice                physicalDevice
962             &planeCountRetrieved, // uint32_t*                    pPropertyCount
963             &planeProps[0]);      // VkDisplayPlanePropertiesKHR*    pProperties
964 
965         // Check amount of data written equals to expected
966         if (planeCountRetrieved != planeCountExpected)
967             TCU_FAIL_STR(string("planeCountRetrieved != planeCountExpected, ") + de::toString(planeCountRetrieved) +
968                          " != " + de::toString(planeCountExpected));
969 
970         if (planeCountRequested >= planeCountReported)
971         {
972             if (result != VK_SUCCESS)
973                 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
974         }
975         else
976         {
977             if (result != VK_INCOMPLETE)
978                 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
979         }
980 
981         // Check the driver has written something
982         for (uint32_t planeIndex = 0; planeIndex < planeCountRetrieved; planeIndex++)
983         {
984             const VkDisplayKHR currentDisplay = planeProps[planeIndex].currentDisplay;
985 
986             results.check(planeProps[planeIndex].currentStackIndex < planeCountReported,
987                           "CurrentStackIndex must be less than the number of planes reported " +
988                               de::toString(planeCountReported));
989 
990             results.check(currentDisplay == DE_NULL || de::contains(displaySet, currentDisplay),
991                           "Plane bound to invalid handle " + de::toString(currentDisplay));
992 
993             if (results.getResult() != QP_TEST_RESULT_PASS)
994             {
995                 m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane "
996                       << planeIndex << " with properties " << planeProps[planeIndex] << tcu::TestLog::EndMessage;
997 
998                 TCU_FAIL_STR(results.getMessage());
999             }
1000         }
1001 
1002         // Check the driver has not written more than requested
1003         if (planeProps[planeCountExpected].currentDisplay != canaryDisplay)
1004             TCU_FAIL("Memory damage detected: driver has written more than expected");
1005     }
1006 
1007     return tcu::TestStatus::pass("pass");
1008 }
1009 
1010 /*--------------------------------------------------------------------*//*!
1011  * \brief Display plane support coverage test
1012  *
1013  * Throws an exception on fail.
1014  *
1015  * \return tcu::TestStatus::pass on success
1016  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneSupportedDisplaysKHR(void)1017 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneSupportedDisplaysKHR(void)
1018 {
1019     uint32_t planeCountReported = 0u;
1020     uint32_t planeCountTested   = 0u;
1021     VkResult result;
1022     DisplayVector displaysVector;
1023     DisplaySet displaySet;
1024 
1025     if (!getDisplays(displaysVector))
1026         TCU_FAIL("Failed to retrieve displays");
1027 
1028     if (displaysVector.empty())
1029         TCU_THROW(NotSupportedError, "No displays reported");
1030 
1031     displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
1032 
1033     result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
1034         m_physicalDevice,    // VkPhysicalDevice                physicalDevice
1035         &planeCountReported, // uint32_t*                    pPropertyCount
1036         DE_NULL);            // VkDisplayPlanePropertiesKHR*    pProperties
1037 
1038     if (result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY &&
1039         result != VK_ERROR_OUT_OF_DEVICE_MEMORY)
1040     {
1041         TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1042     }
1043 
1044     if (result != VK_SUCCESS)
1045         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1046 
1047     if (planeCountReported == 0)
1048         TCU_THROW(ResourceError, "Cannot perform test: no planes supported");
1049 
1050     planeCountTested = planeCountReported;
1051     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1052     {
1053         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
1054               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
1055 
1056         planeCountTested = MAX_TESTED_PLANE_COUNT;
1057     }
1058 
1059     for (uint32_t planeIndex = 0; planeIndex < planeCountTested; planeIndex++)
1060     {
1061         uint32_t displayCountReported = 0u;
1062 
1063         result = m_vki.getDisplayPlaneSupportedDisplaysKHR(m_physicalDevice,      // VkPhysicalDevice    physicalDevice
1064                                                            planeIndex,            // uint32_t            planeIndex
1065                                                            &displayCountReported, // uint32_t*        pDisplayCount
1066                                                            DE_NULL);              // VkDisplayKHR*    pDisplays
1067 
1068         if (result != VK_SUCCESS)
1069             TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1070 
1071         // Test the call correctly writes data in various size arrays
1072         for (uint32_t displayCountRequested = 0; displayCountRequested < displayCountReported + 2;
1073              displayCountRequested++)
1074         {
1075             const uint32_t displayCountExpected = std::min(displayCountRequested, displayCountReported);
1076             const VkDisplayKHR nullDisplay      = DE_NULL;
1077             const VkDisplayKHR canaryDisplay    = static_cast<VkDisplayKHR>(0xABCDEF11);
1078             const uint32_t canaryItemCount      = 1;
1079             std::vector<VkDisplayKHR> displaysForPlane(displayCountRequested + canaryItemCount, nullDisplay);
1080             uint32_t displayCountRetrieved = displayCountRequested;
1081 
1082             displaysForPlane[displayCountExpected] = canaryDisplay;
1083 
1084             result = m_vki.getDisplayPlaneSupportedDisplaysKHR(m_physicalDevice, // VkPhysicalDevice    physicalDevice
1085                                                                planeIndex,       // uint32_t            planeIndex
1086                                                                &displayCountRetrieved, // uint32_t*        pDisplayCount
1087                                                                &displaysForPlane[0]);  // VkDisplayKHR*    pDisplays
1088 
1089             // Check amount of data written equals to expected
1090             if (displayCountRetrieved != displayCountExpected)
1091                 TCU_FAIL_STR(string("displayCountRetrieved != displayCountExpected, ") +
1092                              de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
1093 
1094             if (displayCountRequested >= displayCountReported)
1095             {
1096                 if (result != VK_SUCCESS)
1097                     TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1098             }
1099             else
1100             {
1101                 if (result != VK_INCOMPLETE)
1102                     TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1103             }
1104 
1105             // Check the driver has written something
1106             for (uint32_t displayIndex = 0; displayIndex < displayCountExpected; displayIndex++)
1107             {
1108                 const VkDisplayKHR display = displaysForPlane[displayIndex];
1109 
1110                 if (display != nullDisplay)
1111                 {
1112                     if (!de::contains(displaySet, display))
1113                     {
1114                         TCU_FAIL_STR("Invalid display handle " + de::toString(display));
1115                     }
1116                 }
1117             }
1118 
1119             // Check the driver has not written more than requested
1120             if (displaysForPlane[displayCountExpected] != canaryDisplay)
1121                 TCU_FAIL("Memory damage detected: driver has written more than expected");
1122         }
1123     }
1124 
1125     return tcu::TestStatus::pass("pass");
1126 }
1127 
1128 /*--------------------------------------------------------------------*//*!
1129  * \brief Display mode properties coverage test
1130  *
1131  * Throws an exception on fail.
1132  *
1133  * \return tcu::TestStatus::pass on success
1134  *//*--------------------------------------------------------------------*/
testGetDisplayModePropertiesKHR(void)1135 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModePropertiesKHR(void)
1136 {
1137     VkResult result;
1138     DisplayVector displaysVector;
1139 
1140     if (!getDisplays(displaysVector))
1141         TCU_FAIL("Failed to retrieve displays list");
1142 
1143     if (displaysVector.empty())
1144         TCU_THROW(NotSupportedError, "No displays reported");
1145 
1146     for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++)
1147     {
1148         VkDisplayKHR display        = *it;
1149         uint32_t modesCountReported = 0u;
1150 
1151         result = m_vki.getDisplayModePropertiesKHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
1152                                                    display,          // VkDisplayKHR                    display
1153                                                    &modesCountReported, // uint32_t*                    pPropertyCount
1154                                                    DE_NULL);            // VkDisplayModePropertiesKHR*    pProperties
1155 
1156         // Test the call correctly writes data in various size arrays
1157         for (uint32_t modesCountRequested = 0; modesCountRequested < modesCountReported + 2;
1158              modesCountRequested          = nextTestNumber(modesCountRequested, modesCountReported + 2))
1159         {
1160             const uint32_t modesCountExpected         = std::min(modesCountRequested, modesCountReported);
1161             const VkDisplayModeKHR nullDisplayMode    = DE_NULL;
1162             const VkDisplayModePropertiesKHR nullMode = {nullDisplayMode, // VkDisplayModeKHR                displayMode
1163                                                          {
1164                                                              // VkDisplayModeParametersKHR    parameters
1165                                                              {0, 0}, // VkExtent2D                    visibleRegion
1166                                                              0       // uint32_t                        refreshRate
1167                                                          }};
1168             const VkDisplayModeKHR canaryDisplayMode  = static_cast<VkDisplayModeKHR>(0xABCDEF11);
1169             const uint32_t canaryItemCount            = 1;
1170             std::vector<VkDisplayModePropertiesKHR> modesForDisplay(modesCountRequested + canaryItemCount, nullMode);
1171             uint32_t modesCountRetrieved = modesCountRequested;
1172 
1173             modesForDisplay[modesCountExpected].displayMode = canaryDisplayMode;
1174 
1175             result =
1176                 m_vki.getDisplayModePropertiesKHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
1177                                                   display,          // VkDisplayKHR                    display
1178                                                   &modesCountRetrieved, // uint32_t*                    pPropertyCount
1179                                                   &modesForDisplay[0]); // VkDisplayModePropertiesKHR*    pProperties
1180 
1181             // Check amount of data written equals to expected
1182             if (modesCountRetrieved != modesCountExpected)
1183                 TCU_FAIL_STR(string("modesCountRetrieved != modesCountExpected, ") + de::toString(modesCountRetrieved) +
1184                              " != " + de::toString(modesCountExpected));
1185 
1186             if (modesCountRequested >= modesCountReported)
1187             {
1188                 if (result != VK_SUCCESS)
1189                     TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1190             }
1191             else
1192             {
1193                 if (result != VK_INCOMPLETE)
1194                     TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1195             }
1196 
1197             // Check the driver has written something
1198             for (uint32_t modeIndex = 0; modeIndex < modesCountExpected; modeIndex++)
1199             {
1200                 const VkDisplayModePropertiesKHR theModeProperties = modesForDisplay[modeIndex];
1201 
1202                 if (theModeProperties.displayMode == nullMode.displayMode)
1203                     TCU_FAIL_STR("Invalid mode display handle reported for display " + de::toString(display));
1204             }
1205 
1206             // Check the driver has not written more than requested
1207             if (modesForDisplay[modesCountExpected].displayMode != canaryDisplayMode)
1208                 TCU_FAIL("Memory damage detected: driver has written more than expected");
1209         }
1210     }
1211 
1212     return tcu::TestStatus::pass("pass");
1213 }
1214 
1215 /*--------------------------------------------------------------------*//*!
1216  * \brief Create display mode coverage test
1217  *
1218  * Throws an exception on fail.
1219  *
1220  * \return tcu::TestStatus::pass on success
1221  *//*--------------------------------------------------------------------*/
testCreateDisplayModeKHR(void)1222 tcu::TestStatus DisplayCoverageTestInstance::testCreateDisplayModeKHR(void)
1223 {
1224     DisplayVector displaysVector;
1225     VkResult result;
1226 
1227     if (!getDisplays(displaysVector))
1228         TCU_FAIL("Failed to retrieve displays");
1229 
1230     if (displaysVector.empty())
1231         TCU_THROW(NotSupportedError, "No displays reported");
1232 
1233     for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++)
1234     {
1235         const VkDisplayKHR display                               = *it;
1236         DisplayModePropertiesVector::size_type builtinModesCount = 0u;
1237         VkDisplayModePropertiesKHR validModeProperties;
1238         VkDisplayModeKHR mode = DE_NULL;
1239         DisplayModePropertiesVector modes;
1240         VkDisplayModeCreateInfoKHR createInfo = {
1241             VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR, // VkStructureType                sType
1242             DE_NULL,                                        // const void*                    pNext
1243             0,                                              // VkDisplayModeCreateFlagsKHR    flags
1244             {
1245                 // VkDisplayModeParametersKHR    parameters
1246                 {0, 0}, // VkExtent2D                    visibleRegion
1247                 0       // uint32_t                        refreshRate
1248             }};
1249 
1250         if (!getDisplayModeProperties(display, modes))
1251             TCU_FAIL("Failed to retrieve display mode properties");
1252 
1253         if (modes.size() < 1)
1254             TCU_FAIL("At least one mode expected to be returned");
1255 
1256         // Builtin mode count should not be updated with a new mode. Get initial builtin mode count
1257         builtinModesCount = modes.size();
1258 
1259         // Assume first available builtin mode as a valid mode sample
1260         validModeProperties = modes[0];
1261 
1262         // Do negative test by making one of parameters unacceptable
1263         for (uint32_t testIndex = 0; testIndex < 3; testIndex++)
1264         {
1265             VkDisplayModeCreateInfoKHR createInfoFail(createInfo);
1266             VkDisplayModeKHR modeFail = DE_NULL;
1267 
1268             createInfoFail.parameters = validModeProperties.parameters;
1269 
1270             switch (testIndex)
1271             {
1272             case 0:
1273                 createInfoFail.parameters.refreshRate = 0;
1274                 break;
1275             case 1:
1276                 createInfoFail.parameters.visibleRegion.width = 0;
1277                 break;
1278             case 2:
1279                 createInfoFail.parameters.visibleRegion.height = 0;
1280                 break;
1281             default:
1282                 DE_FATAL("Impossible");
1283                 break;
1284             }
1285 
1286             result =
1287                 m_vki.createDisplayModeKHR(m_physicalDevice, // VkPhysicalDevice                        physicalDevice
1288                                            display,          // VkDisplayKHR                            display
1289                                            &createInfoFail,  // const VkDisplayModeCreateInfoKHR*    pCreateInfo
1290                                            DE_NULL,          // const VkAllocationCallbacks*            pAllocator
1291                                            &modeFail);       // VkDisplayModeKHR*                    pMode
1292 
1293             if (result != VK_ERROR_INITIALIZATION_FAILED)
1294                 TCU_FAIL_STR(string("Expected VK_ERROR_INITIALIZATION_FAILED. Have ") + getResultAsString(result));
1295 
1296             if (modeFail != DE_NULL)
1297                 TCU_FAIL("Mode should be kept invalid on fail");
1298         }
1299 
1300         // At last create valid display mode
1301         createInfo.parameters = validModeProperties.parameters;
1302 
1303         result = m_vki.createDisplayModeKHR(m_physicalDevice, // VkPhysicalDevice                        physicalDevice
1304                                             display,          // VkDisplayKHR                            display
1305                                             &createInfo,      // const VkDisplayModeCreateInfoKHR*    pCreateInfo
1306                                             DE_NULL,          // const VkAllocationCallbacks*            pAllocator
1307                                             &mode);           // VkDisplayModeKHR*                    pMode
1308 
1309         if (result != VK_SUCCESS)
1310             TCU_FAIL_STR("Expected VK_SUCCESS. Have " + getResultAsString(result));
1311 
1312         if (mode == DE_NULL)
1313             TCU_FAIL("Valid handle expected");
1314 
1315         // Builtin mode count should not be updated with a new mode
1316         modes.clear();
1317 
1318         if (!getDisplayModeProperties(display, modes))
1319             TCU_FAIL("Failed to retrieve display mode properties");
1320 
1321         if (builtinModesCount != modes.size())
1322             TCU_FAIL_STR(string("Mode count has changed from ") + de::toString(builtinModesCount) + string(" to ") +
1323                          de::toString(modes.size()));
1324     }
1325 
1326     return tcu::TestStatus::pass("pass");
1327 }
1328 
1329 /*--------------------------------------------------------------------*//*!
1330  * \brief Display-plane capabilities coverage test
1331  *
1332  * Throws an exception on fail.
1333  *
1334  * \return tcu::TestStatus::pass on success
1335  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneCapabilitiesKHR(void)1336 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneCapabilitiesKHR(void)
1337 {
1338     uint32_t planeCountReported = 0u;
1339     VkResult result;
1340 
1341     result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
1342         m_physicalDevice,    // VkPhysicalDevice                physicalDevice
1343         &planeCountReported, // uint32_t*                    pPropertyCount
1344         DE_NULL);            // VkDisplayPlanePropertiesKHR*    pProperties
1345 
1346     if (result != VK_SUCCESS)
1347         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1348 
1349     if (planeCountReported == 0)
1350     {
1351         DisplayVector displaysVector;
1352 
1353         // If we don't have any displays then it's alright to have no planes, as
1354         // per the Vulkan Spec:
1355         //        Devices must support at least one plane on each display
1356         if (!getDisplays(displaysVector))
1357             TCU_FAIL("Failed to retrieve displays");
1358 
1359         if (displaysVector.empty())
1360             TCU_THROW(NotSupportedError, "No display planes reported");
1361 
1362         TCU_FAIL("No planes defined");
1363     }
1364 
1365     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1366     {
1367         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
1368               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
1369 
1370         planeCountReported = MAX_TESTED_PLANE_COUNT;
1371     }
1372 
1373     for (uint32_t planeIndex = 0; planeIndex < planeCountReported; planeIndex++)
1374     {
1375         std::vector<VkDisplayKHR> displaysForPlane;
1376 
1377         if (!getDisplaysForPlane(planeIndex, displaysForPlane))
1378             TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
1379 
1380         if (displaysForPlane.empty())
1381             continue;
1382 
1383         // Check the driver has written something
1384         for (uint32_t displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++)
1385         {
1386             const VkDisplayKHR display = displaysForPlane[displayIndex];
1387             std::vector<VkDisplayModePropertiesKHR> modesPropertiesForDisplay;
1388 
1389             if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
1390                 TCU_FAIL("Failed to retrieve display mode properties");
1391 
1392             for (uint32_t modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++)
1393             {
1394                 const VkDisplayModeKHR theDisplayMode           = modesPropertiesForDisplay[modeIndex].displayMode;
1395                 const uint32_t unrecognizedAlphaFlags           = ~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
1396                 VkDisplayPlaneCapabilitiesKHR planeCapabilities = {
1397                     unrecognizedAlphaFlags, // VkDisplayPlaneAlphaFlagsKHR supportedAlpha;
1398                     {-1, -1},               // VkOffset2D minSrcPosition;
1399                     {-1, -1},               // VkOffset2D maxSrcPosition;
1400                     {1, 1},                 // VkExtent2D minSrcExtent;
1401                     {0, 0},                 // VkExtent2D maxSrcExtent;
1402                     {1, 1},                 // VkOffset2D minDstPosition;
1403                     {0, 0},                 // VkOffset2D maxDstPosition;
1404                     {1, 1},                 // VkExtent2D minDstExtent;
1405                     {0, 0},                 // VkExtent2D maxDstExtent;
1406                 };
1407                 tcu::ResultCollector results(m_log);
1408 
1409                 result = m_vki.getDisplayPlaneCapabilitiesKHR(
1410                     m_physicalDevice,    // VkPhysicalDevice                    physicalDevice
1411                     theDisplayMode,      // VkDisplayModeKHR                    mode
1412                     planeIndex,          // uint32_t                            planeIndex
1413                     &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR*    pCapabilities
1414 
1415                 results.check(result == VK_SUCCESS, string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1416 
1417                 results.check((planeCapabilities.supportedAlpha & unrecognizedAlphaFlags) == 0,
1418                               "supportedAlpha contains unrecognized value");
1419 
1420                 results.check((planeCapabilities.supportedAlpha & RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS) != 0u,
1421                               "supportedAlpha contains no known flags");
1422 
1423                 results.check(planeCapabilities.minSrcPosition.x >= 0, "minSrcPosition.x >= 0");
1424 
1425                 results.check(planeCapabilities.minSrcPosition.y >= 0, "minSrcPosition.y >= 0");
1426 
1427                 results.check(planeCapabilities.maxSrcPosition.x >= 0, "maxSrcPosition.x >= 0");
1428 
1429                 results.check(planeCapabilities.maxSrcPosition.y >= 0, "maxSrcPosition.y >= 0");
1430 
1431                 results.check(planeCapabilities.minSrcPosition.x <= planeCapabilities.maxSrcPosition.x,
1432                               "minSrcPosition.x <= maxSrcPosition.x");
1433 
1434                 results.check(planeCapabilities.minSrcPosition.y <= planeCapabilities.maxSrcPosition.y,
1435                               "minSrcPosition.y <= maxSrcPosition.y");
1436 
1437                 results.check(planeCapabilities.minDstPosition.x <= planeCapabilities.maxDstPosition.x,
1438                               "minDstPosition.x <= maxDstPosition.x");
1439 
1440                 results.check(planeCapabilities.minDstPosition.y <= planeCapabilities.maxDstPosition.y,
1441                               "minDstPosition.y <= maxDstPosition.y");
1442 
1443                 results.check(planeCapabilities.minSrcExtent.width <= planeCapabilities.maxSrcExtent.width,
1444                               "minSrcExtent.width <= maxSrcExtent.width");
1445 
1446                 results.check(planeCapabilities.minSrcExtent.height <= planeCapabilities.maxSrcExtent.height,
1447                               "minSrcExtent.height <= maxSrcExtent.height");
1448 
1449                 results.check(planeCapabilities.minDstExtent.width <= planeCapabilities.maxDstExtent.width,
1450                               "minDstExtent.width <= maxDstExtent.width");
1451 
1452                 results.check(planeCapabilities.minDstExtent.height <= planeCapabilities.maxDstExtent.height,
1453                               "minDstExtent.height <= maxDstExtent.height");
1454 
1455                 if (results.getResult() != QP_TEST_RESULT_PASS)
1456                 {
1457                     m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane's "
1458                           << planeIndex << " display " << displayIndex << " and mode " << modeIndex
1459                           << " with capabilities " << planeCapabilities << tcu::TestLog::EndMessage;
1460 
1461                     TCU_FAIL_STR(results.getMessage());
1462                 }
1463             }
1464         }
1465     }
1466 
1467     return tcu::TestStatus::pass("pass");
1468 }
1469 
1470 namespace
1471 {
1472 struct SurfaceCountersError : public std::runtime_error
1473 {
SurfaceCountersErrorvkt::wsi::__anon828035c80111::SurfaceCountersError1474     SurfaceCountersError(const std::string &what_) : std::runtime_error(what_)
1475     {
1476     }
1477 };
1478 } // namespace
1479 
1480 /*--------------------------------------------------------------------*//*!
1481  * \brief Test display surface creation or counters.
1482  *
1483  * In the counter variant, it needs VK_EXT_display_surface_counter
1484  * and checks the available surface counters.
1485  *
1486  * Throws an exception on fail.
1487  *
1488  * \return tcu::TestStatus::pass on success
1489  *//*--------------------------------------------------------------------*/
testDisplaySurface(SurfaceTestKind testKind)1490 tcu::TestStatus DisplayCoverageTestInstance::testDisplaySurface(SurfaceTestKind testKind)
1491 {
1492     uint32_t planeCountReported  = 0u;
1493     uint32_t planeCountTested    = 0u;
1494     uint32_t planeCountRetrieved = 0u;
1495     std::vector<VkDisplayPlanePropertiesKHR> planeProperties;
1496     bool testPerformed = false;
1497     DisplayVector displaysVector;
1498     VkResult result;
1499     std::string surfaceCountersErr;
1500 
1501     DE_ASSERT(testKind >= 0 && testKind < SURFACE_TEST_KIND_MAX_ENUM);
1502 
1503     // Check the needed extension.
1504     if (testKind == SURFACE_COUNTERS &&
1505         (!isInstanceExtensionSupported(m_context.getUsedApiVersion(), m_context.getInstanceExtensions(),
1506                                        "VK_EXT_display_surface_counter")))
1507         TCU_THROW(NotSupportedError, "VK_EXT_display_surface_counter not supported");
1508 
1509     // Get displays
1510     if (!getDisplays(displaysVector))
1511         TCU_FAIL("Failed to retrieve displays");
1512 
1513     if (displaysVector.empty())
1514         TCU_THROW(NotSupportedError, "No displays reported");
1515 
1516     // Get planes
1517     result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
1518         m_physicalDevice,    // VkPhysicalDevice                physicalDevice
1519         &planeCountReported, // uint32_t*                    pPropertyCount
1520         DE_NULL);            // VkDisplayPlanePropertiesKHR*    pProperties
1521 
1522     if (result != VK_SUCCESS)
1523         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1524 
1525     if (planeCountReported == 0)
1526         TCU_FAIL("No planes defined");
1527 
1528     planeCountTested = planeCountReported;
1529     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1530     {
1531         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
1532               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
1533 
1534         planeCountTested = MAX_TESTED_PLANE_COUNT;
1535     }
1536 
1537     planeProperties.resize(planeCountTested);
1538     planeCountRetrieved = planeCountTested;
1539 
1540     result = m_vki.getPhysicalDeviceDisplayPlanePropertiesKHR(
1541         m_physicalDevice,     // VkPhysicalDevice                physicalDevice
1542         &planeCountRetrieved, // uint32_t*                    pPropertyCount
1543         &planeProperties[0]); // VkDisplayPlanePropertiesKHR*    pProperties
1544 
1545     if (result != VK_SUCCESS && result != VK_INCOMPLETE)
1546         TCU_FAIL_STR(string("Expected VK_SUCCESS or VK_INCOMPLETE expected. Have ") + getResultAsString(result));
1547 
1548     if (planeCountRetrieved != planeCountTested)
1549         TCU_FAIL_STR(string("Number of planes requested (") + de::toString(planeCountTested) +
1550                      ") does not match retrieved (" + de::toString(planeCountRetrieved) + ")");
1551 
1552     // Iterate through displays-modes
1553     for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++)
1554     {
1555         const VkDisplayKHR display = *it;
1556         std::vector<VkDisplayModePropertiesKHR> modesPropertiesForDisplay;
1557 
1558         if (!getDisplayModeProperties(display, modesPropertiesForDisplay))
1559             TCU_FAIL("Failed to retrieve display mode properties");
1560 
1561         for (uint32_t modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++)
1562         {
1563             const VkDisplayModeKHR displayMode               = modesPropertiesForDisplay[modeIndex].displayMode;
1564             const VkDisplayModePropertiesKHR &modeProperties = modesPropertiesForDisplay[modeIndex];
1565 
1566             for (uint32_t planeIndex = 0; planeIndex < planeCountTested; planeIndex++)
1567             {
1568                 std::vector<VkDisplayKHR> displaysForPlane;
1569 
1570                 if (!getDisplaysForPlane(planeIndex, displaysForPlane))
1571                     TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
1572 
1573                 if (displaysForPlane.empty())
1574                     continue;
1575 
1576                 // Iterate through displays supported by the plane
1577                 for (uint32_t displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++)
1578                 {
1579                     const VkDisplayKHR planeDisplay = displaysForPlane[displayIndex];
1580                     VkDisplayPlaneCapabilitiesKHR planeCapabilities;
1581                     bool fullDisplayPlane;
1582 
1583                     if (display == planeDisplay)
1584                     {
1585                         deMemset(&planeCapabilities, 0, sizeof(planeCapabilities));
1586 
1587                         result = m_vki.getDisplayPlaneCapabilitiesKHR(
1588                             m_physicalDevice,    // VkPhysicalDevice                    physicalDevice
1589                             displayMode,         // VkDisplayModeKHR                    mode
1590                             planeIndex,          // uint32_t                            planeIndex
1591                             &planeCapabilities); // VkDisplayPlaneCapabilitiesKHR*    pCapabilities
1592 
1593                         if (result != VK_SUCCESS)
1594                             TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1595 
1596                         fullDisplayPlane =
1597                             planeCapabilities.minDstExtent.height == modeProperties.parameters.visibleRegion.height &&
1598                             planeCapabilities.minDstExtent.width == modeProperties.parameters.visibleRegion.width;
1599 
1600                         if (fullDisplayPlane &&
1601                             (planeCapabilities.supportedAlpha & VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR) != 0)
1602                         {
1603                             const VkDisplayPlaneAlphaFlagBitsKHR alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
1604                             const VkInstance instance                      = m_context.getInstance();
1605                             const VkDisplaySurfaceCreateInfoKHR createInfo = {
1606                                 VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, // VkStructureType                    sType
1607                                 DE_NULL,     // const void*                        pNext
1608                                 0,           // VkDisplaySurfaceCreateFlagsKHR    flags
1609                                 displayMode, // VkDisplayModeKHR                    displayMode
1610                                 planeIndex,  // uint32_t                            planeIndex
1611                                 planeProperties[planeIndex]
1612                                     .currentStackIndex, // uint32_t                            planeStackIndex
1613                                 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, // VkSurfaceTransformFlagBitsKHR    transform
1614                                 1.0f,                                  // float                            globalAlpha
1615                                 alphaMode,                             // VkDisplayPlaneAlphaFlagBitsKHR    alphaMode
1616                                 {                                      // VkExtent2D                        imageExtent
1617                                  planeCapabilities.minDstExtent.width, planeCapabilities.minDstExtent.height}};
1618                             VkSurfaceKHR surface = DE_NULL;
1619 
1620                             result = m_vki.createDisplayPlaneSurfaceKHR(
1621                                 instance,    // VkInstance                            instance
1622                                 &createInfo, // const VkDisplaySurfaceCreateInfoKHR*    pCreateInfo
1623                                 DE_NULL,     // const VkAllocationCallbacks*            pAllocator
1624                                 &surface);   // VkSurfaceKHR*                        pSurface
1625 
1626                             if (result != VK_SUCCESS)
1627                                 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1628 
1629                             if (surface == DE_NULL)
1630                                 TCU_FAIL("Invalid surface handle returned");
1631 
1632                             if (testKind == SURFACE_COUNTERS)
1633                             {
1634                                 // Check surface counters.
1635                                 try
1636                                 {
1637                                     const vk::VkSurfaceCapabilities2EXT capsExt =
1638                                         vk::wsi::getPhysicalDeviceSurfaceCapabilities2EXT(m_vki, m_physicalDevice,
1639                                                                                           surface);
1640                                     const vk::VkSurfaceCapabilitiesKHR capsKhr =
1641                                         vk::wsi::getPhysicalDeviceSurfaceCapabilities(m_vki, m_physicalDevice, surface);
1642 
1643                                     if (!vk::wsi::sameSurfaceCapabilities(capsKhr, capsExt))
1644                                     {
1645                                         throw SurfaceCountersError("KHR and EXT surface capabilities do not match");
1646                                     }
1647 
1648                                     for (uint32_t i = 0; i < sizeof(capsExt.supportedSurfaceCounters) * 8; ++i)
1649                                     {
1650                                         uint32_t mask = (1 << i);
1651                                         if (capsExt.supportedSurfaceCounters & mask)
1652                                         {
1653                                             if (mask != static_cast<uint32_t>(VK_SURFACE_COUNTER_VBLANK_EXT))
1654                                             {
1655                                                 std::ostringstream msg;
1656                                                 msg << "Invalid bit set in supportedSurfaceCounters: 0x" << std::hex
1657                                                     << mask;
1658                                                 throw SurfaceCountersError(msg.str());
1659                                             }
1660                                         }
1661                                     }
1662                                 }
1663                                 catch (const SurfaceCountersError &err)
1664                                 {
1665                                     surfaceCountersErr = err.what();
1666                                 }
1667                             }
1668 
1669                             m_vki.destroySurfaceKHR(instance, // VkInstance                            instance
1670                                                     surface,  // VkSurfaceKHR*                        pSurface
1671                                                     DE_NULL); // const VkAllocationCallbacks*            pAllocator
1672 
1673                             testPerformed = true;
1674                         }
1675                     }
1676                 }
1677             }
1678         }
1679     }
1680 
1681     if (!testPerformed)
1682         TCU_THROW(NotSupportedError, "Cannot find suitable parameters for the test");
1683 
1684     return ((surfaceCountersErr.empty()) ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail(surfaceCountersErr));
1685 }
1686 
1687 /*--------------------------------------------------------------------*//*!
1688  * \brief Display enumeration coverage test using VK_KHR_get_display_properties2
1689  *
1690  * Throws an exception on fail.
1691  *
1692  * \return tcu::TestStatus::pass on success
1693  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayProperties2KHR(void)1694 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayProperties2KHR(void)
1695 {
1696     uint32_t displayCountReported = 0u;
1697     uint32_t displayCountToTest   = 0u;
1698     tcu::ResultCollector results(m_log);
1699     VkResult result;
1700 
1701     result =
1702         m_vki.getPhysicalDeviceDisplayProperties2KHR(m_physicalDevice, // VkPhysicalDevice            physicalDevice
1703                                                      &displayCountReported, // uint32_t*                pPropertyCount
1704                                                      DE_NULL);              // VkDisplayProperties2KHR*    pProperties
1705 
1706     if (result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY &&
1707         result != VK_ERROR_OUT_OF_DEVICE_MEMORY)
1708     {
1709         TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1710     }
1711 
1712     if (result != VK_SUCCESS)
1713         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1714 
1715     if (displayCountReported == 0)
1716         TCU_THROW(NotSupportedError, std::string("Cannot perform test: no displays found").c_str());
1717 
1718     displayCountToTest = displayCountReported;
1719     if (displayCountReported > MAX_TESTED_DISPLAY_COUNT)
1720     {
1721         m_log << tcu::TestLog::Message << "Number of displays reported is too high " << displayCountReported
1722               << ". Test is limited to " << MAX_TESTED_DISPLAY_COUNT << tcu::TestLog::EndMessage;
1723 
1724         displayCountToTest = MAX_TESTED_DISPLAY_COUNT;
1725     }
1726 
1727     // Test the call correctly writes data in various size arrays
1728     for (uint32_t displayCountRequested = 0; displayCountRequested < displayCountToTest + 2; displayCountRequested++)
1729     {
1730         const uint32_t displayCountExpected = std::min(displayCountRequested, displayCountReported);
1731         const VkDisplayPropertiesKHR nonUpdatedDisplayProperties = {
1732             // Most values are set to fail the test to make sure driver updates them
1733             DE_NULL,                             // VkDisplayKHR                    display
1734             DE_NULL,                             // const char*                    displayName
1735             {0, 0},                              // VkExtent2D                    physicalDimensions
1736             {0, 0},                              // VkExtent2D                    physicalResolution
1737             ~RECOGNIZED_SURFACE_TRANSFORM_FLAGS, // VkSurfaceTransformFlagsKHR    supportedTransforms
1738             (vk::VkBool32)(VK_TRUE + 1),         // VkBool32                        planeReorderPossible
1739             (vk::VkBool32)(VK_TRUE + 1)          // VkBool32                        persistentContent
1740         };
1741         const VkStructureType queryStructureType                   = VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR;
1742         const VkDisplayProperties2KHR nonUpdatedDisplayProperties2 = {
1743             queryStructureType,         // VkStructureType            sType
1744             DE_NULL,                    // void*                    pNext
1745             nonUpdatedDisplayProperties // VkDisplayPropertiesKHR    displayProperties
1746         };
1747         const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11);
1748         const uint32_t canaryItemCount   = 1;
1749         std::vector<VkDisplayProperties2KHR> displaysProps2(displayCountRequested + canaryItemCount,
1750                                                             nonUpdatedDisplayProperties2);
1751         uint32_t displayCountRetrieved = displayCountRequested;
1752         DisplaySet displaySet;
1753 
1754         displaysProps2[displayCountExpected].displayProperties.display = canaryDisplay;
1755 
1756         result = m_vki.getPhysicalDeviceDisplayProperties2KHR(
1757             m_physicalDevice,       // VkPhysicalDevice            physicalDevice
1758             &displayCountRetrieved, // uint32_t*                pPropertyCount
1759             &displaysProps2[0]);    // VkDisplayProperties2KHR*    pProperties
1760 
1761         // Check amount of data written equals to expected
1762         if (displayCountRetrieved != displayCountExpected)
1763             TCU_FAIL_STR(string("displayCountRetrieved != displayCountExpected, ") +
1764                          de::toString(displayCountRetrieved) + " != " + de::toString(displayCountExpected));
1765 
1766         if (displayCountRequested >= displayCountReported)
1767         {
1768             if (result != VK_SUCCESS)
1769                 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1770         }
1771         else
1772         {
1773             if (result != VK_INCOMPLETE)
1774                 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1775         }
1776 
1777         // Check the driver has written something
1778         for (uint32_t displayIndex = 0; displayIndex < displayCountRetrieved; displayIndex++)
1779         {
1780             const VkDisplayProperties2KHR &properties2 = displaysProps2[displayIndex];
1781             const VkDisplayPropertiesKHR &properties   = properties2.displayProperties;
1782 
1783             displaySet.insert(properties.display);
1784 
1785             results.check(properties2.sType == queryStructureType,
1786                           "sType has changed to " + de::toString(properties2.sType));
1787 
1788             results.check(properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext));
1789 
1790             validateDisplayProperties(results, properties, nonUpdatedDisplayProperties);
1791 
1792             if (results.getResult() != QP_TEST_RESULT_PASS)
1793             {
1794                 m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for display "
1795                       << displayIndex << " with properties " << properties2 << " non updated display properties are "
1796                       << nonUpdatedDisplayProperties2 << tcu::TestLog::EndMessage;
1797 
1798                 TCU_FAIL_STR(results.getMessage());
1799             }
1800         }
1801 
1802         // Check the driver has not written more than requested
1803         if (displaysProps2[displayCountExpected].displayProperties.display != canaryDisplay)
1804             TCU_FAIL("Memory damage detected: driver has written more than expected");
1805 
1806         // Check display handle uniqueness
1807         if (displaySet.size() != displayCountRetrieved)
1808             TCU_FAIL("Display handle duplication detected");
1809     }
1810 
1811     return tcu::TestStatus::pass("pass");
1812 }
1813 
1814 /*--------------------------------------------------------------------*//*!
1815  * \brief Plane enumeration coverage test using VK_KHR_get_display_properties2
1816  *
1817  * Throws an exception on fail.
1818  *
1819  * \return tcu::TestStatus::pass on success
1820  *//*--------------------------------------------------------------------*/
testGetPhysicalDeviceDisplayPlaneProperties2KHR(void)1821 tcu::TestStatus DisplayCoverageTestInstance::testGetPhysicalDeviceDisplayPlaneProperties2KHR(void)
1822 {
1823     DisplayVector displaysVector;
1824     DisplaySet displaySet;
1825     uint32_t planeCountReported = 0u;
1826     uint32_t planeCountTested   = 0u;
1827     tcu::ResultCollector results(m_log);
1828     VkResult result;
1829 
1830     // Create a list of displays available
1831     if (!getDisplays2(displaysVector))
1832         TCU_FAIL("Failed to retrieve displays");
1833 
1834     if (displaysVector.empty())
1835         TCU_THROW(NotSupportedError, "No displays reported");
1836 
1837     displaySet = DisplaySet(displaysVector.begin(), displaysVector.end());
1838 
1839     // Get planes to test
1840     result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(
1841         m_physicalDevice,    // VkPhysicalDevice                    physicalDevice
1842         &planeCountReported, // uint32_t*                        pPropertyCount
1843         DE_NULL);            // VkDisplayPlaneProperties2KHR*    pProperties
1844 
1845     if (result != VK_SUCCESS && result != VK_INCOMPLETE && result != VK_ERROR_OUT_OF_HOST_MEMORY &&
1846         result != VK_ERROR_OUT_OF_DEVICE_MEMORY)
1847     {
1848         TCU_FAIL_STR(string("Invalid result ") + getResultAsString(result));
1849     }
1850 
1851     if (result != VK_SUCCESS)
1852         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1853 
1854     if (planeCountReported == 0)
1855         TCU_THROW(ResourceError, "Cannot perform test: no planes found");
1856 
1857     planeCountTested = planeCountReported;
1858     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1859     {
1860         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
1861               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
1862 
1863         planeCountTested = MAX_TESTED_PLANE_COUNT;
1864     }
1865 
1866     // Test the call correctly writes data in various size arrays
1867     for (uint32_t planeCountRequested = 0; planeCountRequested < planeCountTested + 2; planeCountRequested++)
1868     {
1869         const uint32_t planeCountExpected                           = std::min(planeCountRequested, planeCountReported);
1870         const VkDisplayPlanePropertiesKHR nonUpdatedPlaneProperties = {
1871             // Most values are set to fail the test to make sure driver updates them
1872             DE_NULL,           // VkDisplayKHR    currentDisplay
1873             planeCountReported // uint32_t        currentStackIndex
1874         };
1875         const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR;
1876         const VkDisplayPlaneProperties2KHR nonUpdatedPlaneProperties2 = {
1877             queryStructureType,       // VkStructureType                sType
1878             DE_NULL,                  // void*                        pNext
1879             nonUpdatedPlaneProperties // VkDisplayPlanePropertiesKHR    displayPlaneProperties
1880         };
1881         const VkDisplayKHR canaryDisplay = static_cast<VkDisplayKHR>(0xABCDEF11);
1882         const uint32_t canaryItemCount   = 1;
1883         std::vector<VkDisplayPlaneProperties2KHR> planeProps2(planeCountRequested + canaryItemCount,
1884                                                               nonUpdatedPlaneProperties2);
1885         uint32_t planeCountRetrieved = planeCountRequested;
1886 
1887         planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay = canaryDisplay;
1888 
1889         result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(
1890             m_physicalDevice,     // VkPhysicalDevice                    physicalDevice
1891             &planeCountRetrieved, // uint32_t*                        pPropertyCount
1892             &planeProps2[0]);     // VkDisplayPlaneProperties2KHR*    pProperties
1893 
1894         // Check amount of data written equals to expected
1895         if (planeCountRetrieved != planeCountExpected)
1896             TCU_FAIL_STR(string("planeCountRetrieved != planeCountExpected, ") + de::toString(planeCountRetrieved) +
1897                          " != " + de::toString(planeCountExpected));
1898 
1899         if (planeCountRequested >= planeCountReported)
1900         {
1901             if (result != VK_SUCCESS)
1902                 TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1903         }
1904         else
1905         {
1906             if (result != VK_INCOMPLETE)
1907                 TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
1908         }
1909 
1910         // Check the driver has written something
1911         for (uint32_t planeIndex = 0; planeIndex < planeCountRetrieved; planeIndex++)
1912         {
1913             const VkDisplayPlaneProperties2KHR &properties2 = planeProps2[planeIndex];
1914             const VkDisplayPlanePropertiesKHR &properties   = properties2.displayPlaneProperties;
1915 
1916             results.check(properties2.sType == queryStructureType,
1917                           "sType has changed to " + de::toString(properties2.sType));
1918 
1919             results.check(properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext));
1920 
1921             validateDisplayPlaneProperties(results, properties, nonUpdatedPlaneProperties, displaySet);
1922 
1923             if (results.getResult() != QP_TEST_RESULT_PASS)
1924             {
1925                 m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane "
1926                       << planeIndex << " with properties " << properties2 << tcu::TestLog::EndMessage;
1927 
1928                 TCU_FAIL_STR(results.getMessage());
1929             }
1930         }
1931 
1932         // Check the driver has not written more than requested
1933         if (planeProps2[planeCountExpected].displayPlaneProperties.currentDisplay != canaryDisplay)
1934             TCU_FAIL("Memory damage detected: driver has written more than expected");
1935     }
1936 
1937     return tcu::TestStatus::pass("pass");
1938 }
1939 
1940 /*--------------------------------------------------------------------*//*!
1941  * \brief Display-plane capabilities coverage test using VK_KHR_get_display_properties2
1942  *
1943  * Throws an exception on fail.
1944  *
1945  * \return tcu::TestStatus::pass on success
1946  *//*--------------------------------------------------------------------*/
testGetDisplayPlaneCapabilities2KHR(void)1947 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayPlaneCapabilities2KHR(void)
1948 {
1949     uint32_t planeCountReported = 0u;
1950     VkResult result;
1951 
1952     result = m_vki.getPhysicalDeviceDisplayPlaneProperties2KHR(
1953         m_physicalDevice,    // VkPhysicalDevice                    physicalDevice
1954         &planeCountReported, // uint32_t*                        pPropertyCount
1955         DE_NULL);            // VkDisplayPlaneProperties2KHR*    pProperties
1956 
1957     if (result != VK_SUCCESS)
1958         TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
1959 
1960     if (planeCountReported == 0)
1961         TCU_THROW(NotSupportedError, "No display plane reported");
1962 
1963     if (planeCountReported > MAX_TESTED_PLANE_COUNT)
1964     {
1965         m_log << tcu::TestLog::Message << "Number of planes reported is too high " << planeCountReported
1966               << ". Test is limited to " << MAX_TESTED_PLANE_COUNT << tcu::TestLog::EndMessage;
1967 
1968         planeCountReported = MAX_TESTED_PLANE_COUNT;
1969     }
1970 
1971     for (uint32_t planeIndex = 0; planeIndex < planeCountReported; planeIndex++)
1972     {
1973         std::vector<VkDisplayKHR> displaysForPlane;
1974 
1975         if (!getDisplaysForPlane(planeIndex, displaysForPlane))
1976             TCU_FAIL_STR("Failed to retrieve displays list for plane " + de::toString(planeIndex));
1977 
1978         if (displaysForPlane.empty())
1979             continue;
1980 
1981         // Check the driver has written something
1982         for (uint32_t displayIndex = 0; displayIndex < displaysForPlane.size(); displayIndex++)
1983         {
1984             const VkDisplayKHR display = displaysForPlane[displayIndex];
1985             std::vector<VkDisplayModeProperties2KHR> modesPropertiesForDisplay;
1986 
1987             if (!getDisplayModeProperties2(display, modesPropertiesForDisplay))
1988                 TCU_FAIL("Failed to retrieve display mode properties");
1989 
1990             for (uint32_t modeIndex = 0; modeIndex < modesPropertiesForDisplay.size(); modeIndex++)
1991             {
1992                 const VkDisplayModeKHR displayMode =
1993                     modesPropertiesForDisplay[modeIndex].displayModeProperties.displayMode;
1994                 const uint32_t unrecognizedAlphaFlags   = ~RECOGNIZED_DISPLAY_PLANE_ALPHA_FLAGS;
1995                 const VkDisplayPlaneInfo2KHR planeInfo2 = {
1996                     VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR, // VkStructureType    sType
1997                     DE_NULL,                                    // const void*        pNext
1998                     displayMode,                                // VkDisplayModeKHR    mode
1999                     planeIndex                                  // uint32_t            planeIndex
2000                 };
2001                 VkDisplayPlaneCapabilitiesKHR planeCapabilities = {
2002                     unrecognizedAlphaFlags, // VkDisplayPlaneAlphaFlagsKHR    supportedAlpha
2003                     {-1, -1},               // VkOffset2D                    minSrcPosition
2004                     {-1, -1},               // VkOffset2D                    maxSrcPosition
2005                     {1, 1},                 // VkExtent2D                    minSrcExtent
2006                     {0, 0},                 // VkExtent2D                    maxSrcExtent
2007                     {1, 1},                 // VkOffset2D                    minDstPosition
2008                     {0, 0},                 // VkOffset2D                    maxDstPosition
2009                     {1, 1},                 // VkExtent2D                    minDstExtent
2010                     {0, 0},                 // VkExtent2D                    maxDstExtent
2011                 };
2012                 const VkStructureType queryStructureType          = VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR;
2013                 VkDisplayPlaneCapabilities2KHR planeCapabilities2 = {
2014                     queryStructureType, // VkStructureType                    sType
2015                     DE_NULL,            // void*                            pNext
2016                     planeCapabilities   // VkDisplayPlaneCapabilitiesKHR    capabilities
2017                 };
2018                 tcu::ResultCollector results(m_log);
2019 
2020                 result = m_vki.getDisplayPlaneCapabilities2KHR(
2021                     m_physicalDevice,     // VkPhysicalDevice                    physicalDevice
2022                     &planeInfo2,          // const VkDisplayPlaneInfo2KHR*    pDisplayPlaneInfo
2023                     &planeCapabilities2); // VkDisplayPlaneCapabilities2KHR*    pCapabilities
2024 
2025                 results.check(result == VK_SUCCESS, string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
2026 
2027                 results.check(planeCapabilities2.sType == queryStructureType,
2028                               "sType has changed to " + de::toString(planeCapabilities2.sType));
2029 
2030                 results.check(planeCapabilities2.pNext == DE_NULL,
2031                               "pNext has changed to " + de::toString(planeCapabilities2.pNext));
2032 
2033                 // Validate results returned by driver in planeCapabilities2 using non-updated planeCapabilities
2034                 validateDisplayPlaneCapabilities(results, planeCapabilities2.capabilities, planeCapabilities);
2035 
2036                 if (results.getResult() != QP_TEST_RESULT_PASS)
2037                 {
2038                     m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for plane's "
2039                           << planeIndex << " display " << displayIndex << " and mode " << modeIndex
2040                           << " with capabilities " << planeCapabilities2 << tcu::TestLog::EndMessage;
2041 
2042                     TCU_FAIL_STR(results.getMessage());
2043                 }
2044             }
2045         }
2046     }
2047 
2048     return tcu::TestStatus::pass("pass");
2049 }
2050 
2051 /*--------------------------------------------------------------------*//*!
2052  * \brief Display mode properties coverage test using VK_KHR_get_display_properties2
2053  *
2054  * Throws an exception on fail.
2055  *
2056  * \return tcu::TestStatus::pass on success
2057  *//*--------------------------------------------------------------------*/
testGetDisplayModeProperties2KHR(void)2058 tcu::TestStatus DisplayCoverageTestInstance::testGetDisplayModeProperties2KHR(void)
2059 {
2060     VkResult result;
2061     tcu::ResultCollector results(m_log);
2062     DisplayVector displaysVector;
2063 
2064     if (!getDisplays2(displaysVector))
2065         TCU_FAIL("Failed to retrieve displays list");
2066 
2067     if (displaysVector.empty())
2068         TCU_THROW(NotSupportedError, "No displays reported");
2069 
2070     for (DisplayVector::iterator it = displaysVector.begin(); it != displaysVector.end(); it++)
2071     {
2072         VkDisplayKHR display        = *it;
2073         uint32_t modesCountReported = 0u;
2074 
2075         result = m_vki.getDisplayModeProperties2KHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
2076                                                     display,          // VkDisplayKHR                    display
2077                                                     &modesCountReported, // uint32_t*                    pPropertyCount
2078                                                     DE_NULL);            // VkDisplayModeProperties2KHR*    pProperties
2079 
2080         // Test the call correctly writes data in various size arrays
2081         for (uint32_t modesCountRequested = 0; modesCountRequested < modesCountReported + 2;
2082              modesCountRequested          = nextTestNumber(modesCountRequested, modesCountReported + 2))
2083         {
2084             const uint32_t modesCountExpected      = std::min(modesCountRequested, modesCountReported);
2085             const VkDisplayModeKHR nullDisplayMode = DE_NULL;
2086             const VkDisplayModePropertiesKHR nonUpdatedModeProperties = {
2087                 nullDisplayMode, // VkDisplayModeKHR                displayMode
2088                 {
2089                     // VkDisplayModeParametersKHR    parameters
2090                     {0, 0}, // VkExtent2D                    visibleRegion
2091                     0       // uint32_t                        refreshRate
2092                 }};
2093             const VkStructureType queryStructureType = VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR;
2094             const VkDisplayModeProperties2KHR nonUpdatedModeProperties2 = {
2095                 queryStructureType,      // VkStructureType                sType
2096                 DE_NULL,                 // void*                        pNext
2097                 nonUpdatedModeProperties // VkDisplayModePropertiesKHR    displayModeProperties
2098             };
2099             const VkDisplayModeKHR canaryDisplayMode = static_cast<VkDisplayModeKHR>(0xABCDEF11);
2100             const uint32_t canaryItemCount           = 1;
2101             std::vector<VkDisplayModeProperties2KHR> modesProperties2(modesCountRequested + canaryItemCount,
2102                                                                       nonUpdatedModeProperties2);
2103             uint32_t modesCountRetrieved = modesCountRequested;
2104 
2105             modesProperties2[modesCountExpected].displayModeProperties.displayMode = canaryDisplayMode;
2106 
2107             result =
2108                 m_vki.getDisplayModeProperties2KHR(m_physicalDevice, // VkPhysicalDevice                physicalDevice
2109                                                    display,          // VkDisplayKHR                    display
2110                                                    &modesCountRetrieved,  // uint32_t*                    pPropertyCount
2111                                                    &modesProperties2[0]); // VkDisplayModeProperties2KHR*    pProperties
2112 
2113             // Check amount of data written equals to expected
2114             if (modesCountRetrieved != modesCountExpected)
2115                 TCU_FAIL_STR(string("modesCountRetrieved != modesCountExpected, ") + de::toString(modesCountRetrieved) +
2116                              " != " + de::toString(modesCountExpected));
2117 
2118             if (modesCountRequested >= modesCountReported)
2119             {
2120                 if (result != VK_SUCCESS)
2121                     TCU_FAIL_STR(string("Expected VK_SUCCESS. Have ") + getResultAsString(result));
2122             }
2123             else
2124             {
2125                 if (result != VK_INCOMPLETE)
2126                     TCU_FAIL_STR(string("Expected VK_INCOMPLETE. Have ") + getResultAsString(result));
2127             }
2128 
2129             // Check the driver has written something
2130             for (uint32_t modeIndex = 0; modeIndex < modesCountExpected; modeIndex++)
2131             {
2132                 const VkDisplayModeProperties2KHR &properties2 = modesProperties2[modeIndex];
2133                 const VkDisplayModePropertiesKHR &properties   = properties2.displayModeProperties;
2134 
2135                 results.check(properties2.sType == queryStructureType,
2136                               "sType has changed to " + de::toString(properties2.sType));
2137 
2138                 results.check(properties2.pNext == DE_NULL, "pNext has changed to " + de::toString(properties2.pNext));
2139 
2140                 validateDisplayModeProperties(results, properties, nonUpdatedModeProperties);
2141 
2142                 if (results.getResult() != QP_TEST_RESULT_PASS)
2143                 {
2144                     m_log << tcu::TestLog::Message << "Error detected " << results.getMessage() << " for mode "
2145                           << modeIndex << " with properties " << properties2 << " non updated mode properties are "
2146                           << nonUpdatedModeProperties2 << tcu::TestLog::EndMessage;
2147 
2148                     TCU_FAIL_STR(results.getMessage());
2149                 }
2150             }
2151 
2152             // Check the driver has not written more than requested
2153             if (modesProperties2[modesCountExpected].displayModeProperties.displayMode != canaryDisplayMode)
2154                 TCU_FAIL("Memory damage detected: driver has written more than expected");
2155         }
2156     }
2157 
2158     return tcu::TestStatus::pass("pass");
2159 }
2160 
2161 /*--------------------------------------------------------------------*//*!
2162  * \brief Display coverage tests case class
2163  *//*--------------------------------------------------------------------*/
2164 class DisplayCoverageTestsCase : public vkt::TestCase
2165 {
2166 public:
DisplayCoverageTestsCase(tcu::TestContext & context,const char * name,const DisplayIndexTest testId)2167     DisplayCoverageTestsCase(tcu::TestContext &context, const char *name, const DisplayIndexTest testId)
2168         : TestCase(context, name)
2169         , m_testId(testId)
2170     {
2171     }
2172 
2173 private:
2174     const DisplayIndexTest m_testId;
2175 
createInstance(vkt::Context & context) const2176     vkt::TestInstance *createInstance(vkt::Context &context) const
2177     {
2178         return new DisplayCoverageTestInstance(context, m_testId);
2179     }
2180 };
2181 
2182 /*--------------------------------------------------------------------*//*!
2183  * \brief Adds a test into group
2184  *//*--------------------------------------------------------------------*/
addTest(tcu::TestCaseGroup * group,const DisplayIndexTest testId,const char * name)2185 static void addTest(tcu::TestCaseGroup *group, const DisplayIndexTest testId, const char *name)
2186 {
2187     tcu::TestContext &testCtx = group->getTestContext();
2188 
2189     group->addChild(new DisplayCoverageTestsCase(testCtx, name, testId));
2190 }
2191 
2192 /*--------------------------------------------------------------------*//*!
2193  * \brief Adds VK_KHR_display and VK_KHR_display_swapchain extension tests into group
2194  *//*--------------------------------------------------------------------*/
createDisplayCoverageTests(tcu::TestCaseGroup * group)2195 void createDisplayCoverageTests(tcu::TestCaseGroup *group)
2196 {
2197     // VK_KHR_display extension tests
2198     // Display enumeration coverage test
2199     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES, "get_display_properties");
2200     // Planes enumeration coverage test
2201     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES, "get_display_plane_properties");
2202     // Display plane support coverage test
2203     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_SUPPORTED_DISPLAY, "get_display_plane_supported_displays");
2204     // Display mode properties coverage test
2205     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE, "get_display_mode_properties");
2206     // Create display mode coverage test
2207     addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_MODE, "create_display_mode");
2208     // Display-plane capabilities coverage test
2209     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES, "get_display_plane_capabilities");
2210     // Create display plane surface coverage test
2211     addTest(group, DISPLAY_TEST_INDEX_CREATE_DISPLAY_PLANE_SURFACE, "create_display_plane_surface");
2212     // Display plane surface counters test
2213     addTest(group, DISPLAY_TEST_INDEX_SURFACE_COUNTERS, "surface_counters");
2214 
2215     // VK_KHR_get_display_properties2 extension tests
2216     // Display enumeration coverage test using VK_KHR_get_display_properties2
2217     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PROPERTIES2, "get_display_properties2");
2218     // Planes enumeration coverage test using VK_KHR_get_display_properties2
2219     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANES2, "get_display_plane_properties2");
2220     // Display mode properties coverage test using VK_KHR_get_display_properties2
2221     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_MODE2, "get_display_mode_properties2");
2222     // Display-plane capabilities coverage test using VK_KHR_get_display_properties2
2223     addTest(group, DISPLAY_TEST_INDEX_GET_DISPLAY_PLANE_CAPABILITIES2, "get_display_plane_capabilities2");
2224 }
2225 
2226 } // namespace wsi
2227 } // namespace vkt
2228