Merge vk-gl-cts/vulkan-cts-1.1.1 into vk-gl-cts/vulkan-cts-1.1.2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / wsi / vktWsiColorSpaceTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google 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 VkSwapchain Tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktWsiSwapchainTests.hpp"
25
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkPlatform.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkDeviceUtil.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkWsiPlatform.hpp"
41 #include "vkWsiUtil.hpp"
42 #include "vkAllocationCallbackUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkObjUtil.hpp"
45
46 #include "tcuTestLog.hpp"
47 #include "tcuFormatUtil.hpp"
48 #include "tcuPlatform.hpp"
49 #include "tcuResultCollector.hpp"
50
51 #include "deUniquePtr.hpp"
52 #include "deStringUtil.hpp"
53 #include "deArrayUtil.hpp"
54 #include "deSharedPtr.hpp"
55
56 #include <limits>
57
58 namespace vkt
59 {
60 namespace wsi
61 {
62
63 namespace
64 {
65
66 using namespace vk;
67 using namespace vk::wsi;
68
69 using tcu::TestLog;
70 using tcu::Maybe;
71 using tcu::UVec2;
72
73 using de::MovePtr;
74 using de::UniquePtr;
75
76 using std::string;
77 using std::vector;
78
79 typedef vector<VkExtensionProperties> Extensions;
80
81 void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
82 {
83         for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
84                  requiredExtName != requiredExtensions.end();
85                  ++requiredExtName)
86         {
87                 if (!isExtensionSupported(supportedExtensions, RequiredExtension(*requiredExtName)))
88                         TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
89         }
90 }
91
92 Move<VkInstance> createInstanceWithWsi (const PlatformInterface&                vkp,
93                                                                                 deUint32                                                version,
94                                                                                 const Extensions&                               supportedExtensions,
95                                                                                 Type                                                    wsiType,
96                                                                                 const VkAllocationCallbacks*    pAllocator      = DE_NULL)
97 {
98         vector<string>  extensions;
99
100         extensions.push_back("VK_KHR_surface");
101         extensions.push_back(getExtensionName(wsiType));
102
103         // VK_EXT_swapchain_colorspace adds new surface formats. Driver can enumerate
104         // the formats regardless of whether VK_EXT_swapchain_colorspace was enabled,
105         // but using them without enabling the extension is not allowed. Thus we have
106         // two options:
107         //
108         // 1) Filter out non-core formats to stay within valid usage.
109         //
110         // 2) Enable VK_EXT_swapchain colorspace if advertised by the driver.
111         //
112         // We opt for (2) as it provides basic coverage for the extension as a bonus.
113         if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_swapchain_colorspace")))
114                 extensions.push_back("VK_EXT_swapchain_colorspace");
115
116         checkAllSupported(supportedExtensions, extensions);
117
118         return createDefaultInstance(vkp, version, vector<string>(), extensions, pAllocator);
119 }
120
121 VkPhysicalDeviceFeatures getDeviceFeaturesForWsi (void)
122 {
123         VkPhysicalDeviceFeatures features;
124         deMemset(&features, 0, sizeof(features));
125         return features;
126 }
127
128 Move<VkDevice> createDeviceWithWsi (const vk::PlatformInterface&        vkp,
129                                                                         vk::VkInstance                                  instance,
130                                                                         const InstanceInterface&                vki,
131                                                                         VkPhysicalDevice                                physicalDevice,
132                                                                         const Extensions&                               supportedExtensions,
133                                                                         const deUint32                                  queueFamilyIndex,
134                                                                         const VkAllocationCallbacks*    pAllocator = DE_NULL)
135 {
136         const float                                             queuePriorities[]       = { 1.0f };
137         const VkDeviceQueueCreateInfo   queueInfos[]            =
138         {
139                 {
140                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
141                         DE_NULL,
142                         (VkDeviceQueueCreateFlags)0,
143                         queueFamilyIndex,
144                         DE_LENGTH_OF_ARRAY(queuePriorities),
145                         &queuePriorities[0]
146                 }
147         };
148         const VkPhysicalDeviceFeatures  features                = getDeviceFeaturesForWsi();
149         vector<const char*>             extensions;
150
151         if (!isExtensionSupported(supportedExtensions, RequiredExtension("VK_KHR_swapchain")))
152                 TCU_THROW(NotSupportedError, (string(extensions[0]) + " is not supported").c_str());
153         extensions.push_back("VK_KHR_swapchain");
154
155         if (isExtensionSupported(supportedExtensions, RequiredExtension("VK_EXT_hdr_metadata")))
156                 extensions.push_back("VK_EXT_hdr_metadata");
157
158         const VkDeviceCreateInfo                deviceParams    =
159         {
160                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
161                 DE_NULL,
162                 (VkDeviceCreateFlags)0,
163                 DE_LENGTH_OF_ARRAY(queueInfos),
164                 &queueInfos[0],
165                 0u,                                                                     // enabledLayerCount
166                 DE_NULL,                                                        // ppEnabledLayerNames
167                 (deUint32)extensions.size(),
168                 extensions.empty() ? DE_NULL : &extensions[0],
169                 &features
170         };
171
172         return createDevice(vkp, instance, vki, physicalDevice, &deviceParams, pAllocator);
173 }
174
175 deUint32 getNumQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice)
176 {
177         deUint32        numFamilies             = 0;
178
179         vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
180
181         return numFamilies;
182 }
183
184 vector<deUint32> getSupportedQueueFamilyIndices (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
185 {
186         const deUint32          numTotalFamilyIndices   = getNumQueueFamilyIndices(vki, physicalDevice);
187         vector<deUint32>        supportedFamilyIndices;
188
189         for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
190         {
191                 if (getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
192                         supportedFamilyIndices.push_back(queueFamilyNdx);
193         }
194
195         return supportedFamilyIndices;
196 }
197
198 deUint32 chooseQueueFamilyIndex (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
199 {
200         const vector<deUint32>  supportedFamilyIndices  = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
201
202         if (supportedFamilyIndices.empty())
203                 TCU_THROW(NotSupportedError, "Device doesn't support presentation");
204
205         return supportedFamilyIndices[0];
206 }
207
208 struct InstanceHelper
209 {
210         const vector<VkExtensionProperties>     supportedExtensions;
211         const Unique<VkInstance>                        instance;
212         const InstanceDriver                            vki;
213
214         InstanceHelper (Context& context, Type wsiType, const VkAllocationCallbacks* pAllocator = DE_NULL)
215                 : supportedExtensions   (enumerateInstanceExtensionProperties(context.getPlatformInterface(),
216                                                                                                                                           DE_NULL))
217                 , instance                              (createInstanceWithWsi(context.getPlatformInterface(),
218                                                                                                            context.getUsedApiVersion(),
219                                                                                                            supportedExtensions,
220                                                                                                            wsiType,
221                                                                                                            pAllocator))
222                 , vki                                   (context.getPlatformInterface(), *instance)
223         {}
224 };
225
226 struct DeviceHelper
227 {
228         const VkPhysicalDevice  physicalDevice;
229         const deUint32                  queueFamilyIndex;
230         const Unique<VkDevice>  device;
231         const DeviceDriver              vkd;
232         const VkQueue                   queue;
233
234         DeviceHelper (Context&                                          context,
235                                   const InstanceInterface&              vki,
236                                   VkInstance                                    instance,
237                                   VkSurfaceKHR                                  surface,
238                                   const VkAllocationCallbacks*  pAllocator = DE_NULL)
239                 : physicalDevice        (chooseDevice(vki, instance, context.getTestContext().getCommandLine()))
240                 , queueFamilyIndex      (chooseQueueFamilyIndex(vki, physicalDevice, surface))
241                 , device                        (createDeviceWithWsi(context.getPlatformInterface(),
242                                                                                                  instance,
243                                                                                                  vki,
244                                                                                                  physicalDevice,
245                                                                                                  enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL),
246                                                                                                  queueFamilyIndex,
247                                                                                                  pAllocator))
248                 , vkd                           (context.getPlatformInterface(), instance, *device)
249                 , queue                         (getDeviceQueue(vkd, *device, queueFamilyIndex, 0))
250         {
251         }
252 };
253
254 MovePtr<Display> createDisplay (const vk::Platform&     platform,
255                                                                 const Extensions&       supportedExtensions,
256                                                                 Type                            wsiType)
257 {
258         try
259         {
260                 return MovePtr<Display>(platform.createWsiDisplay(wsiType));
261         }
262         catch (const tcu::NotSupportedError& e)
263         {
264                 if (isExtensionSupported(supportedExtensions, RequiredExtension(getExtensionName(wsiType))))
265                 {
266                         // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
267                         // must support creating native display & window for that WSI type.
268                         throw tcu::TestError(e.getMessage());
269                 }
270                 else
271                         throw;
272         }
273 }
274
275 MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
276 {
277         try
278         {
279                 return MovePtr<Window>(display.createWindow(initialSize));
280         }
281         catch (const tcu::NotSupportedError& e)
282         {
283                 // See createDisplay - assuming that wsi::Display was supported platform port
284                 // should also support creating a window.
285                 throw tcu::TestError(e.getMessage());
286         }
287 }
288
289 struct NativeObjects
290 {
291         const UniquePtr<Display>        display;
292         const UniquePtr<Window>         window;
293
294         NativeObjects (Context&                         context,
295                                    const Extensions&    supportedExtensions,
296                                    Type                                 wsiType,
297                                    const Maybe<UVec2>&  initialWindowSize = tcu::nothing<UVec2>())
298                 : display       (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
299                 , window        (createWindow(*display, initialWindowSize))
300         {}
301 };
302
303 enum TestDimension
304 {
305         TEST_DIMENSION_MIN_IMAGE_COUNT = 0,     //!< Test all supported image counts
306         TEST_DIMENSION_IMAGE_FORMAT,            //!< Test all supported formats
307         TEST_DIMENSION_IMAGE_EXTENT,            //!< Test various (supported) extents
308         TEST_DIMENSION_IMAGE_ARRAY_LAYERS,
309         TEST_DIMENSION_IMAGE_USAGE,
310         TEST_DIMENSION_IMAGE_SHARING_MODE,
311         TEST_DIMENSION_PRE_TRANSFORM,
312         TEST_DIMENSION_COMPOSITE_ALPHA,
313         TEST_DIMENSION_PRESENT_MODE,
314         TEST_DIMENSION_CLIPPED,
315
316         TEST_DIMENSION_LAST
317 };
318
319 struct TestParameters
320 {
321         Type                    wsiType;
322         TestDimension   dimension;
323
324         TestParameters (Type wsiType_, TestDimension dimension_)
325                 : wsiType       (wsiType_)
326                 , dimension     (dimension_)
327         {}
328
329         TestParameters (void)
330                 : wsiType       (TYPE_LAST)
331                 , dimension     (TEST_DIMENSION_LAST)
332         {}
333 };
334
335 struct GroupParameters
336 {
337         typedef FunctionInstance1<TestParameters>::Function     Function;
338
339         Type            wsiType;
340         Function        function;
341
342         GroupParameters (Type wsiType_, Function function_)
343                 : wsiType       (wsiType_)
344                 , function      (function_)
345         {}
346
347         GroupParameters (void)
348                 : wsiType       (TYPE_LAST)
349                 , function      ((Function)DE_NULL)
350         {}
351 };
352
353 VkSwapchainCreateInfoKHR getBasicSwapchainParameters (Type                                              wsiType,
354                                                                                                           const InstanceInterface&      vki,
355                                                                                                           VkPhysicalDevice                      physicalDevice,
356                                                                                                           VkSurfaceKHR                          surface,
357                                                                                                           VkSurfaceFormatKHR            surfaceFormat,
358                                                                                                           const tcu::UVec2&                     desiredSize,
359                                                                                                           deUint32                                      desiredImageCount)
360 {
361         const VkSurfaceCapabilitiesKHR          capabilities            = getPhysicalDeviceSurfaceCapabilities(vki,
362                                                                                                                                                                                                    physicalDevice,
363                                                                                                                                                                                                    surface);
364         const PlatformProperties&                       platformProperties      = getPlatformProperties(wsiType);
365         const VkSurfaceTransformFlagBitsKHR transform                   = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
366         const VkSwapchainCreateInfoKHR          parameters                      =
367         {
368                 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
369                 DE_NULL,
370                 (VkSwapchainCreateFlagsKHR)0,
371                 surface,
372                 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
373                 surfaceFormat.format,
374                 surfaceFormat.colorSpace,
375                 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
376                         ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
377                 1u,                                                                     // imageArrayLayers
378                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
379                 VK_SHARING_MODE_EXCLUSIVE,
380                 0u,
381                 (const deUint32*)DE_NULL,
382                 transform,
383                 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
384                 VK_PRESENT_MODE_FIFO_KHR,
385                 VK_FALSE,                                                       // clipped
386                 (VkSwapchainKHR)0                                       // oldSwapchain
387         };
388
389         return parameters;
390 }
391
392 typedef de::SharedPtr<Unique<VkImageView> >             ImageViewSp;
393 typedef de::SharedPtr<Unique<VkFramebuffer> >   FramebufferSp;
394
395 class TriangleRenderer
396 {
397 public:
398                                                                         TriangleRenderer        (const DeviceInterface&         vkd,
399                                                                                                                  const VkDevice                         device,
400                                                                                                                  Allocator&                                     allocator,
401                                                                                                                  const BinaryCollection&        binaryRegistry,
402                                                                                                                  const vector<VkImage>          swapchainImages,
403                                                                                                                  const VkFormat                         framebufferFormat,
404                                                                                                                  const UVec2&                           renderSize);
405                                                                         ~TriangleRenderer       (void);
406
407         void                                                    recordFrame                     (VkCommandBuffer                        cmdBuffer,
408                                                                                                                  deUint32                                       imageNdx,
409                                                                                                                  deUint32                                       frameNdx) const;
410
411         static void                                             getPrograms                     (SourceCollections& dst);
412
413 private:
414         static Move<VkRenderPass>               createRenderPass        (const DeviceInterface&         vkd,
415                                                                                                                  const VkDevice                         device,
416                                                                                                                  const VkFormat                         colorAttachmentFormat);
417         static Move<VkPipelineLayout>   createPipelineLayout(const DeviceInterface&             vkd,
418                                                                                                                  VkDevice                                       device);
419         static Move<VkPipeline>                 createPipeline          (const DeviceInterface&         vkd,
420                                                                                                                  const VkDevice                         device,
421                                                                                                                  const VkRenderPass                     renderPass,
422                                                                                                                  const VkPipelineLayout         pipelineLayout,
423                                                                                                                  const BinaryCollection&        binaryCollection,
424                                                                                                                  const UVec2&                           renderSize);
425
426         static Move<VkImageView>                createAttachmentView(const DeviceInterface&             vkd,
427                                                                                                                  const VkDevice                         device,
428                                                                                                                  const VkImage                          image,
429                                                                                                                  const VkFormat                         format);
430         static Move<VkFramebuffer>              createFramebuffer       (const DeviceInterface&         vkd,
431                                                                                                                  const VkDevice                         device,
432                                                                                                                  const VkRenderPass                     renderPass,
433                                                                                                                  const VkImageView                      colorAttachment,
434                                                                                                                  const UVec2&                           renderSize);
435
436         static Move<VkBuffer>                   createBuffer            (const DeviceInterface&         vkd,
437                                                                                                                  VkDevice                                       device,
438                                                                                                                  VkDeviceSize                           size,
439                                                                                                                  VkBufferUsageFlags                     usage);
440
441         const DeviceInterface&                  m_vkd;
442
443         const vector<VkImage>                   m_swapchainImages;
444         const tcu::UVec2                                m_renderSize;
445
446         const Unique<VkRenderPass>              m_renderPass;
447         const Unique<VkPipelineLayout>  m_pipelineLayout;
448         const Unique<VkPipeline>                m_pipeline;
449
450         const Unique<VkBuffer>                  m_vertexBuffer;
451         const UniquePtr<Allocation>             m_vertexBufferMemory;
452
453         vector<ImageViewSp>                             m_attachmentViews;
454         vector<FramebufferSp>                   m_framebuffers;
455 };
456
457 Move<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface&   vkd,
458                                                                                                            const VkDevice                       device,
459                                                                                                            const VkFormat                       colorAttachmentFormat)
460 {
461         const VkAttachmentDescription   colorAttDesc            =
462         {
463                 (VkAttachmentDescriptionFlags)0,
464                 colorAttachmentFormat,
465                 VK_SAMPLE_COUNT_1_BIT,
466                 VK_ATTACHMENT_LOAD_OP_CLEAR,
467                 VK_ATTACHMENT_STORE_OP_STORE,
468                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
469                 VK_ATTACHMENT_STORE_OP_DONT_CARE,
470                 VK_IMAGE_LAYOUT_UNDEFINED,
471                 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
472         };
473         const VkAttachmentReference             colorAttRef                     =
474         {
475                 0u,
476                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
477         };
478         const VkSubpassDescription              subpassDesc                     =
479         {
480                 (VkSubpassDescriptionFlags)0u,
481                 VK_PIPELINE_BIND_POINT_GRAPHICS,
482                 0u,                                                     // inputAttachmentCount
483                 DE_NULL,                                        // pInputAttachments
484                 1u,                                                     // colorAttachmentCount
485                 &colorAttRef,                           // pColorAttachments
486                 DE_NULL,                                        // pResolveAttachments
487                 DE_NULL,                                        // depthStencilAttachment
488                 0u,                                                     // preserveAttachmentCount
489                 DE_NULL,                                        // pPreserveAttachments
490         };
491         const VkSubpassDependency               dependencies[]          =
492         {
493                 {
494                         VK_SUBPASS_EXTERNAL,    // srcSubpass
495                         0u,                                             // dstSubpass
496                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
497                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
498                         VK_ACCESS_MEMORY_READ_BIT,
499                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
500                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
501                         VK_DEPENDENCY_BY_REGION_BIT
502                 },
503                 {
504                         0u,                                             // srcSubpass
505                         VK_SUBPASS_EXTERNAL,    // dstSubpass
506                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
507                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
508                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
509                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
510                         VK_ACCESS_MEMORY_READ_BIT,
511                         VK_DEPENDENCY_BY_REGION_BIT
512                 },
513         };
514         const VkRenderPassCreateInfo    renderPassParams        =
515         {
516                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
517                 DE_NULL,
518                 (VkRenderPassCreateFlags)0,
519                 1u,
520                 &colorAttDesc,
521                 1u,
522                 &subpassDesc,
523                 DE_LENGTH_OF_ARRAY(dependencies),
524                 dependencies,
525         };
526
527         return vk::createRenderPass(vkd, device, &renderPassParams);
528 }
529
530 Move<VkPipelineLayout> TriangleRenderer::createPipelineLayout (const DeviceInterface&   vkd,
531                                                                                                                            const VkDevice                       device)
532 {
533         const VkPushConstantRange                                               pushConstantRange               =
534         {
535                 VK_SHADER_STAGE_VERTEX_BIT,
536                 0u,                                                                                     // offset
537                 (deUint32)sizeof(deUint32),                                     // size
538         };
539         const VkPipelineLayoutCreateInfo                                pipelineLayoutParams    =
540         {
541                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
542                 DE_NULL,
543                 (vk::VkPipelineLayoutCreateFlags)0,
544                 0u,                                                                                     // setLayoutCount
545                 DE_NULL,                                                                        // pSetLayouts
546                 1u,
547                 &pushConstantRange,
548         };
549
550         return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
551 }
552
553 Move<VkPipeline> TriangleRenderer::createPipeline (const DeviceInterface&       vkd,
554                                                                                                    const VkDevice                       device,
555                                                                                                    const VkRenderPass           renderPass,
556                                                                                                    const VkPipelineLayout       pipelineLayout,
557                                                                                                    const BinaryCollection&      binaryCollection,
558                                                                                                    const UVec2&                         renderSize)
559 {
560         // \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
561         //               and can be deleted immediately following that call.
562         const Unique<VkShaderModule>                                    vertShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
563         const Unique<VkShaderModule>                                    fragShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
564         const std::vector<VkViewport>                                   viewports                               (1, makeViewport(renderSize));
565         const std::vector<VkRect2D>                                             scissors                                (1, makeRect2D(renderSize));
566
567         return vk::makeGraphicsPipeline(vkd,                            // const DeviceInterface&            vk
568                                                                         device,                         // const VkDevice                    device
569                                                                         pipelineLayout,         // const VkPipelineLayout            pipelineLayout
570                                                                         *vertShaderModule,      // const VkShaderModule              vertexShaderModule
571                                                                         DE_NULL,                        // const VkShaderModule              tessellationControlShaderModule
572                                                                         DE_NULL,                        // const VkShaderModule              tessellationEvalShaderModule
573                                                                         DE_NULL,                        // const VkShaderModule              geometryShaderModule
574                                                                         *fragShaderModule,      // const VkShaderModule              fragmentShaderModule
575                                                                         renderPass,                     // const VkRenderPass                renderPass
576                                                                         viewports,                      // const std::vector<VkViewport>&    viewports
577                                                                         scissors);                      // const std::vector<VkRect2D>&      scissors
578 }
579
580 Move<VkImageView> TriangleRenderer::createAttachmentView (const DeviceInterface&        vkd,
581                                                                                                                   const VkDevice                        device,
582                                                                                                                   const VkImage                         image,
583                                                                                                                   const VkFormat                        format)
584 {
585         const VkImageViewCreateInfo             viewParams      =
586         {
587                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
588                 DE_NULL,
589                 (VkImageViewCreateFlags)0,
590                 image,
591                 VK_IMAGE_VIEW_TYPE_2D,
592                 format,
593                 vk::makeComponentMappingRGBA(),
594                 {
595                         VK_IMAGE_ASPECT_COLOR_BIT,
596                         0u,                                             // baseMipLevel
597                         1u,                                             // levelCount
598                         0u,                                             // baseArrayLayer
599                         1u,                                             // layerCount
600                 },
601         };
602
603         return vk::createImageView(vkd, device, &viewParams);
604 }
605
606 Move<VkFramebuffer> TriangleRenderer::createFramebuffer (const DeviceInterface&         vkd,
607                                                                                                                  const VkDevice                         device,
608                                                                                                                  const VkRenderPass                     renderPass,
609                                                                                                                  const VkImageView                      colorAttachment,
610                                                                                                                  const UVec2&                           renderSize)
611 {
612         const VkFramebufferCreateInfo   framebufferParams       =
613         {
614                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
615                 DE_NULL,
616                 (VkFramebufferCreateFlags)0,
617                 renderPass,
618                 1u,
619                 &colorAttachment,
620                 renderSize.x(),
621                 renderSize.y(),
622                 1u,                                                     // layers
623         };
624
625         return vk::createFramebuffer(vkd, device, &framebufferParams);
626 }
627
628 Move<VkBuffer> TriangleRenderer::createBuffer (const DeviceInterface&   vkd,
629                                                                                            VkDevice                                     device,
630                                                                                            VkDeviceSize                         size,
631                                                                                            VkBufferUsageFlags           usage)
632 {
633         const VkBufferCreateInfo        bufferParams    =
634         {
635                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
636                 DE_NULL,
637                 (VkBufferCreateFlags)0,
638                 size,
639                 usage,
640                 VK_SHARING_MODE_EXCLUSIVE,
641                 0,
642                 DE_NULL
643         };
644
645         return vk::createBuffer(vkd, device, &bufferParams);
646 }
647
648 TriangleRenderer::TriangleRenderer (const DeviceInterface&      vkd,
649                                                                         const VkDevice                  device,
650                                                                         Allocator&                              allocator,
651                                                                         const BinaryCollection& binaryRegistry,
652                                                                         const vector<VkImage>   swapchainImages,
653                                                                         const VkFormat                  framebufferFormat,
654                                                                         const UVec2&                    renderSize)
655         : m_vkd                                 (vkd)
656         , m_swapchainImages             (swapchainImages)
657         , m_renderSize                  (renderSize)
658         , m_renderPass                  (createRenderPass(vkd, device, framebufferFormat))
659         , m_pipelineLayout              (createPipelineLayout(vkd, device))
660         , m_pipeline                    (createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
661         , m_vertexBuffer                (createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
662         , m_vertexBufferMemory  (allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
663                                                          MemoryRequirement::HostVisible))
664 {
665         m_attachmentViews.resize(swapchainImages.size());
666         m_framebuffers.resize(swapchainImages.size());
667
668         for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
669         {
670                 m_attachmentViews[imageNdx]     = ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
671                 m_framebuffers[imageNdx]        = FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
672         }
673
674         VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
675
676         {
677                 const VkMappedMemoryRange       memRange        =
678                 {
679                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
680                         DE_NULL,
681                         m_vertexBufferMemory->getMemory(),
682                         m_vertexBufferMemory->getOffset(),
683                         VK_WHOLE_SIZE
684                 };
685                 const tcu::Vec4                         vertices[]      =
686                 {
687                         tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
688                         tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
689                         tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
690                 };
691                 DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
692
693                 deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
694                 VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
695         }
696 }
697
698 TriangleRenderer::~TriangleRenderer (void)
699 {
700 }
701
702 void TriangleRenderer::recordFrame (VkCommandBuffer     cmdBuffer,
703                                                                         deUint32                imageNdx,
704                                                                         deUint32                frameNdx) const
705 {
706         const VkFramebuffer     curFramebuffer  = **m_framebuffers[imageNdx];
707
708         beginCommandBuffer(m_vkd, cmdBuffer, 0u);
709
710         beginRenderPass(m_vkd, cmdBuffer, *m_renderPass, curFramebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.125f, 0.25f, 0.75f, 1.0f));
711
712         m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
713
714         {
715                 const VkDeviceSize bindingOffset = 0;
716                 m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
717         }
718
719         m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
720         m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
721         endRenderPass(m_vkd, cmdBuffer);
722
723         endCommandBuffer(m_vkd, cmdBuffer);
724 }
725
726 void TriangleRenderer::getPrograms (SourceCollections& dst)
727 {
728         dst.glslSources.add("tri-vert") << glu::VertexSource(
729                 "#version 310 es\n"
730                 "layout(location = 0) in highp vec4 a_position;\n"
731                 "layout(push_constant) uniform FrameData\n"
732                 "{\n"
733                 "    highp uint frameNdx;\n"
734                 "} frameData;\n"
735                 "void main (void)\n"
736                 "{\n"
737                 "    highp float angle = float(frameData.frameNdx) / 100.0;\n"
738                 "    highp float c     = cos(angle);\n"
739                 "    highp float s     = sin(angle);\n"
740                 "    highp mat4  t     = mat4( c, -s,  0,  0,\n"
741                 "                              s,  c,  0,  0,\n"
742                 "                              0,  0,  1,  0,\n"
743                 "                              0,  0,  0,  1);\n"
744                 "    gl_Position = t * a_position;\n"
745                 "}\n");
746         dst.glslSources.add("tri-frag") << glu::FragmentSource(
747                 "#version 310 es\n"
748                 "layout(location = 0) out lowp vec4 o_color;\n"
749                 "void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
750 }
751
752 typedef de::SharedPtr<Unique<VkCommandBuffer> > CommandBufferSp;
753 typedef de::SharedPtr<Unique<VkFence> >                 FenceSp;
754 typedef de::SharedPtr<Unique<VkSemaphore> >             SemaphoreSp;
755
756 vector<FenceSp> createFences (const DeviceInterface&    vkd,
757                                                           const VkDevice                        device,
758                                                           size_t                                        numFences)
759 {
760         vector<FenceSp> fences(numFences);
761
762         for (size_t ndx = 0; ndx < numFences; ++ndx)
763                 fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device)));
764
765         return fences;
766 }
767
768 vector<SemaphoreSp> createSemaphores (const DeviceInterface&    vkd,
769                                                                           const VkDevice                        device,
770                                                                           size_t                                        numSemaphores)
771 {
772         vector<SemaphoreSp> semaphores(numSemaphores);
773
774         for (size_t ndx = 0; ndx < numSemaphores; ++ndx)
775                 semaphores[ndx] = SemaphoreSp(new Unique<VkSemaphore>(createSemaphore(vkd, device)));
776
777         return semaphores;
778 }
779
780 vector<CommandBufferSp> allocateCommandBuffers (const DeviceInterface&          vkd,
781                                                                                                 const VkDevice                          device,
782                                                                                                 const VkCommandPool                     commandPool,
783                                                                                                 const VkCommandBufferLevel      level,
784                                                                                                 const size_t                            numCommandBuffers)
785 {
786         vector<CommandBufferSp>                         buffers         (numCommandBuffers);
787
788         for (size_t ndx = 0; ndx < numCommandBuffers; ++ndx)
789                 buffers[ndx] = CommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vkd, device, commandPool, level)));
790
791         return buffers;
792 }
793
794 tcu::TestStatus basicExtensionTest (Context& context, Type wsiType)
795 {
796         const tcu::UVec2                                desiredSize             (256, 256);
797         const InstanceHelper                    instHelper              (context, wsiType);
798         const NativeObjects                             native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
799         const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
800         const DeviceHelper                              devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
801
802         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
803                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
804
805         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
806                                                                                                                                                                                   devHelper.physicalDevice,
807                                                                                                                                                                                   *surface);
808
809         bool found = false;
810         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
811         {
812                 if (curFmt->colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
813                 {
814                         found = true;
815                         break;
816                 }
817         }
818         if (!found)
819         {
820                 TCU_THROW(NotSupportedError, "VK_EXT_swapchain_colorspace supported, but no non-SRGB_NONLINEAR_KHR surface formats found.");
821         }
822         return tcu::TestStatus::pass("Extension tests succeeded");
823 }
824
825 tcu::TestStatus surfaceFormatRenderTest (Context& context,
826                                                                                  Type wsiType,
827                                                                                  VkSurfaceKHR surface,
828                                                                                  VkSurfaceFormatKHR curFmt,
829                                                                                  deBool checkHdr = false)
830 {
831         const tcu::UVec2                                        desiredSize             (256, 256);
832         const InstanceHelper                            instHelper              (context, wsiType);
833         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, surface);
834         const DeviceInterface&                          vkd                             = devHelper.vkd;
835         const VkDevice                                          device                  = *devHelper.device;
836         SimpleAllocator                                         allocator               (vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
837
838         const VkSwapchainCreateInfoKHR          swapchainInfo                   = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, surface, curFmt, desiredSize, 2);
839         const Unique<VkSwapchainKHR>            swapchain                               (createSwapchainKHR(vkd, device, &swapchainInfo));
840         const vector<VkImage>                           swapchainImages                 = getSwapchainImages(vkd, device, *swapchain);
841         const vector<VkExtensionProperties>     deviceExtensions                (enumerateDeviceExtensionProperties(instHelper.vki, devHelper.physicalDevice, DE_NULL));
842
843         if (checkHdr && !isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_hdr_metadata")))
844                 TCU_THROW(NotSupportedError, "Extension VK_EXT_hdr_metadata not supported");
845
846         const TriangleRenderer                  renderer                                        (vkd,
847                                                                                                                                  device,
848                                                                                                                                  allocator,
849                                                                                                                                  context.getBinaryCollection(),
850                                                                                                                                  swapchainImages,
851                                                                                                                                  swapchainInfo.imageFormat,
852                                                                                                                                  tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
853
854         const Unique<VkCommandPool>             commandPool                                     (createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
855
856         const size_t                                    maxQueuedFrames                         = swapchainImages.size()*2;
857
858         // We need to keep hold of fences from vkAcquireNextImageKHR to actually
859         // limit number of frames we allow to be queued.
860         const vector<FenceSp>                   imageReadyFences                        (createFences(vkd, device, maxQueuedFrames));
861
862         // We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
863         // the semaphore in same time as the fence we use to meter rendering.
864         const vector<SemaphoreSp>               imageReadySemaphores            (createSemaphores(vkd, device, maxQueuedFrames+1));
865
866         // For rest we simply need maxQueuedFrames as we will wait for image
867         // from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
868         // previous uses must have completed.
869         const vector<SemaphoreSp>               renderingCompleteSemaphores     (createSemaphores(vkd, device, maxQueuedFrames));
870         const vector<CommandBufferSp>   commandBuffers                          (allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));
871
872         try
873         {
874                 const deUint32  numFramesToRender       = 60;
875
876                 for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
877                 {
878                         const VkFence           imageReadyFence         = **imageReadyFences[frameNdx%imageReadyFences.size()];
879                         const VkSemaphore       imageReadySemaphore     = **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
880                         deUint32                        imageNdx                        = ~0u;
881
882                         if (frameNdx >= maxQueuedFrames)
883                                 VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
884
885                         VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
886
887                         {
888                                 const VkResult  acquireResult   = vkd.acquireNextImageKHR(device,
889                                                                                                                                                   *swapchain,
890                                                                                                                                                   std::numeric_limits<deUint64>::max(),
891                                                                                                                                                   imageReadySemaphore,
892                                                                                                                                                   (vk::VkFence)0,
893                                                                                                                                                   &imageNdx);
894
895                                 if (acquireResult == VK_SUBOPTIMAL_KHR)
896                                         context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
897                                 else
898                                         VK_CHECK(acquireResult);
899                         }
900
901                         TCU_CHECK((size_t)imageNdx < swapchainImages.size());
902
903                         {
904                                 const VkSemaphore                       renderingCompleteSemaphore      = **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
905                                 const VkCommandBuffer           commandBuffer                           = **commandBuffers[frameNdx%commandBuffers.size()];
906                                 const VkPipelineStageFlags      waitDstStage                            = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
907                                 const VkSubmitInfo                      submitInfo                                      =
908                                 {
909                                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
910                                         DE_NULL,
911                                         1u,
912                                         &imageReadySemaphore,
913                                         &waitDstStage,
914                                         1u,
915                                         &commandBuffer,
916                                         1u,
917                                         &renderingCompleteSemaphore
918                                 };
919                                 const VkPresentInfoKHR          presentInfo                                     =
920                                 {
921                                         VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
922                                         DE_NULL,
923                                         1u,
924                                         &renderingCompleteSemaphore,
925                                         1u,
926                                         &*swapchain,
927                                         &imageNdx,
928                                         (VkResult*)DE_NULL
929                                 };
930
931                                 if (checkHdr) {
932                                         const VkHdrMetadataEXT hdrData = {
933                                                         VK_STRUCTURE_TYPE_HDR_METADATA_EXT,
934                                                         DE_NULL,
935                                                         makeXYColorEXT(0.680f, 0.320f),
936                                                         makeXYColorEXT(0.265f, 0.690f),
937                                                         makeXYColorEXT(0.150f, 0.060f),
938                                                         makeXYColorEXT(0.3127f, 0.3290f),
939                                                         1000.0,
940                                                         0.0,
941                                                         1000.0,
942                                                         70.0
943                                         };
944                                         vector<VkSwapchainKHR> swapchainArray;
945
946                                         swapchainArray.push_back(*swapchain);
947                                         vkd.setHdrMetadataEXT(device, (deUint32)swapchainArray.size(), swapchainArray.data(), &hdrData);
948                                 }
949
950                                 renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
951                                 VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, imageReadyFence));
952                                 VK_CHECK(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
953                         }
954                 }
955
956                 VK_CHECK(vkd.deviceWaitIdle(device));
957         }
958         catch (...)
959         {
960                 // Make sure device is idle before destroying resources
961                 vkd.deviceWaitIdle(device);
962                 throw;
963         }
964
965         return tcu::TestStatus::pass("Rendering test succeeded");
966 }
967
968 tcu::TestStatus surfaceFormatRenderTests (Context& context, Type wsiType)
969 {
970         const tcu::UVec2                                        desiredSize             (256, 256);
971         const InstanceHelper                            instHelper              (context, wsiType);
972         const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
973         const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
974         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
975
976         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
977                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
978
979         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
980                                                                                                                                                                                          devHelper.physicalDevice,
981                                                                                                                                                                                          *surface);
982         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
983         {
984                 surfaceFormatRenderTest(context, wsiType, *surface, *curFmt);
985         }
986         return tcu::TestStatus::pass("Rendering tests succeeded");
987 }
988
989 tcu::TestStatus surfaceFormatRenderWithHdrTests (Context& context, Type wsiType)
990 {
991         const tcu::UVec2                                        desiredSize             (256, 256);
992         const InstanceHelper                            instHelper              (context, wsiType);
993         const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
994         const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
995         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
996
997         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
998                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
999
1000         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
1001                                                                                                                                                                                   devHelper.physicalDevice,
1002                                                                                                                                                                                   *surface);
1003         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
1004         {
1005                 surfaceFormatRenderTest(context, wsiType, *surface, *curFmt, true);
1006         }
1007         return tcu::TestStatus::pass("Rendering tests succeeded");
1008 }
1009
1010 void getBasicRenderPrograms (SourceCollections& dst, Type)
1011 {
1012         TriangleRenderer::getPrograms(dst);
1013 }
1014
1015 } // anonymous
1016
1017 void createColorSpaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1018 {
1019         addFunctionCase(testGroup, "extensions", "Verify Colorspace Extensions", basicExtensionTest, wsiType);
1020         addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Tests", getBasicRenderPrograms, surfaceFormatRenderTests, wsiType);
1021         addFunctionCaseWithPrograms(testGroup, "hdr", "Basic Rendering Tests with HDR", getBasicRenderPrograms, surfaceFormatRenderWithHdrTests, wsiType);
1022 }
1023
1024 } // wsi
1025 } // vkt