Merge vk-gkl-cts/vulkan-cts-1.1.2 into vk-gl-cts/vulkan-cts-1.1.3
[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                     platform.hasDisplay(wsiType))
266                 {
267                         // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
268                         // must support creating native display & window for that WSI type.
269                         throw tcu::TestError(e.getMessage());
270                 }
271                 else
272                         throw;
273         }
274 }
275
276 MovePtr<Window> createWindow (const Display& display, const Maybe<UVec2>& initialSize)
277 {
278         try
279         {
280                 return MovePtr<Window>(display.createWindow(initialSize));
281         }
282         catch (const tcu::NotSupportedError& e)
283         {
284                 // See createDisplay - assuming that wsi::Display was supported platform port
285                 // should also support creating a window.
286                 throw tcu::TestError(e.getMessage());
287         }
288 }
289
290 struct NativeObjects
291 {
292         const UniquePtr<Display>        display;
293         const UniquePtr<Window>         window;
294
295         NativeObjects (Context&                         context,
296                                    const Extensions&    supportedExtensions,
297                                    Type                                 wsiType,
298                                    const Maybe<UVec2>&  initialWindowSize = tcu::nothing<UVec2>())
299                 : display       (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
300                 , window        (createWindow(*display, initialWindowSize))
301         {}
302 };
303
304 enum TestDimension
305 {
306         TEST_DIMENSION_MIN_IMAGE_COUNT = 0,     //!< Test all supported image counts
307         TEST_DIMENSION_IMAGE_FORMAT,            //!< Test all supported formats
308         TEST_DIMENSION_IMAGE_EXTENT,            //!< Test various (supported) extents
309         TEST_DIMENSION_IMAGE_ARRAY_LAYERS,
310         TEST_DIMENSION_IMAGE_USAGE,
311         TEST_DIMENSION_IMAGE_SHARING_MODE,
312         TEST_DIMENSION_PRE_TRANSFORM,
313         TEST_DIMENSION_COMPOSITE_ALPHA,
314         TEST_DIMENSION_PRESENT_MODE,
315         TEST_DIMENSION_CLIPPED,
316
317         TEST_DIMENSION_LAST
318 };
319
320 struct TestParameters
321 {
322         Type                    wsiType;
323         TestDimension   dimension;
324
325         TestParameters (Type wsiType_, TestDimension dimension_)
326                 : wsiType       (wsiType_)
327                 , dimension     (dimension_)
328         {}
329
330         TestParameters (void)
331                 : wsiType       (TYPE_LAST)
332                 , dimension     (TEST_DIMENSION_LAST)
333         {}
334 };
335
336 struct GroupParameters
337 {
338         typedef FunctionInstance1<TestParameters>::Function     Function;
339
340         Type            wsiType;
341         Function        function;
342
343         GroupParameters (Type wsiType_, Function function_)
344                 : wsiType       (wsiType_)
345                 , function      (function_)
346         {}
347
348         GroupParameters (void)
349                 : wsiType       (TYPE_LAST)
350                 , function      ((Function)DE_NULL)
351         {}
352 };
353
354 VkSwapchainCreateInfoKHR getBasicSwapchainParameters (Type                                              wsiType,
355                                                                                                           const InstanceInterface&      vki,
356                                                                                                           VkPhysicalDevice                      physicalDevice,
357                                                                                                           VkSurfaceKHR                          surface,
358                                                                                                           VkSurfaceFormatKHR            surfaceFormat,
359                                                                                                           const tcu::UVec2&                     desiredSize,
360                                                                                                           deUint32                                      desiredImageCount)
361 {
362         const VkSurfaceCapabilitiesKHR          capabilities            = getPhysicalDeviceSurfaceCapabilities(vki,
363                                                                                                                                                                                                    physicalDevice,
364                                                                                                                                                                                                    surface);
365         const PlatformProperties&                       platformProperties      = getPlatformProperties(wsiType);
366         const VkSurfaceTransformFlagBitsKHR transform                   = (capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : capabilities.currentTransform;
367         const VkSwapchainCreateInfoKHR          parameters                      =
368         {
369                 VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
370                 DE_NULL,
371                 (VkSwapchainCreateFlagsKHR)0,
372                 surface,
373                 de::clamp(desiredImageCount, capabilities.minImageCount, capabilities.maxImageCount > 0 ? capabilities.maxImageCount : capabilities.minImageCount + desiredImageCount),
374                 surfaceFormat.format,
375                 surfaceFormat.colorSpace,
376                 (platformProperties.swapchainExtent == PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE
377                         ? capabilities.currentExtent : vk::makeExtent2D(desiredSize.x(), desiredSize.y())),
378                 1u,                                                                     // imageArrayLayers
379                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
380                 VK_SHARING_MODE_EXCLUSIVE,
381                 0u,
382                 (const deUint32*)DE_NULL,
383                 transform,
384                 VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
385                 VK_PRESENT_MODE_FIFO_KHR,
386                 VK_FALSE,                                                       // clipped
387                 (VkSwapchainKHR)0                                       // oldSwapchain
388         };
389
390         return parameters;
391 }
392
393 typedef de::SharedPtr<Unique<VkImageView> >             ImageViewSp;
394 typedef de::SharedPtr<Unique<VkFramebuffer> >   FramebufferSp;
395
396 class TriangleRenderer
397 {
398 public:
399                                                                         TriangleRenderer        (const DeviceInterface&         vkd,
400                                                                                                                  const VkDevice                         device,
401                                                                                                                  Allocator&                                     allocator,
402                                                                                                                  const BinaryCollection&        binaryRegistry,
403                                                                                                                  const vector<VkImage>          swapchainImages,
404                                                                                                                  const VkFormat                         framebufferFormat,
405                                                                                                                  const UVec2&                           renderSize);
406                                                                         ~TriangleRenderer       (void);
407
408         void                                                    recordFrame                     (VkCommandBuffer                        cmdBuffer,
409                                                                                                                  deUint32                                       imageNdx,
410                                                                                                                  deUint32                                       frameNdx) const;
411
412         static void                                             getPrograms                     (SourceCollections& dst);
413
414 private:
415         static Move<VkRenderPass>               createRenderPass        (const DeviceInterface&         vkd,
416                                                                                                                  const VkDevice                         device,
417                                                                                                                  const VkFormat                         colorAttachmentFormat);
418         static Move<VkPipelineLayout>   createPipelineLayout(const DeviceInterface&             vkd,
419                                                                                                                  VkDevice                                       device);
420         static Move<VkPipeline>                 createPipeline          (const DeviceInterface&         vkd,
421                                                                                                                  const VkDevice                         device,
422                                                                                                                  const VkRenderPass                     renderPass,
423                                                                                                                  const VkPipelineLayout         pipelineLayout,
424                                                                                                                  const BinaryCollection&        binaryCollection,
425                                                                                                                  const UVec2&                           renderSize);
426
427         static Move<VkImageView>                createAttachmentView(const DeviceInterface&             vkd,
428                                                                                                                  const VkDevice                         device,
429                                                                                                                  const VkImage                          image,
430                                                                                                                  const VkFormat                         format);
431         static Move<VkFramebuffer>              createFramebuffer       (const DeviceInterface&         vkd,
432                                                                                                                  const VkDevice                         device,
433                                                                                                                  const VkRenderPass                     renderPass,
434                                                                                                                  const VkImageView                      colorAttachment,
435                                                                                                                  const UVec2&                           renderSize);
436
437         static Move<VkBuffer>                   createBuffer            (const DeviceInterface&         vkd,
438                                                                                                                  VkDevice                                       device,
439                                                                                                                  VkDeviceSize                           size,
440                                                                                                                  VkBufferUsageFlags                     usage);
441
442         const DeviceInterface&                  m_vkd;
443
444         const vector<VkImage>                   m_swapchainImages;
445         const tcu::UVec2                                m_renderSize;
446
447         const Unique<VkRenderPass>              m_renderPass;
448         const Unique<VkPipelineLayout>  m_pipelineLayout;
449         const Unique<VkPipeline>                m_pipeline;
450
451         const Unique<VkBuffer>                  m_vertexBuffer;
452         const UniquePtr<Allocation>             m_vertexBufferMemory;
453
454         vector<ImageViewSp>                             m_attachmentViews;
455         vector<FramebufferSp>                   m_framebuffers;
456 };
457
458 Move<VkRenderPass> TriangleRenderer::createRenderPass (const DeviceInterface&   vkd,
459                                                                                                            const VkDevice                       device,
460                                                                                                            const VkFormat                       colorAttachmentFormat)
461 {
462         const VkAttachmentDescription   colorAttDesc            =
463         {
464                 (VkAttachmentDescriptionFlags)0,
465                 colorAttachmentFormat,
466                 VK_SAMPLE_COUNT_1_BIT,
467                 VK_ATTACHMENT_LOAD_OP_CLEAR,
468                 VK_ATTACHMENT_STORE_OP_STORE,
469                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
470                 VK_ATTACHMENT_STORE_OP_DONT_CARE,
471                 VK_IMAGE_LAYOUT_UNDEFINED,
472                 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
473         };
474         const VkAttachmentReference             colorAttRef                     =
475         {
476                 0u,
477                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
478         };
479         const VkSubpassDescription              subpassDesc                     =
480         {
481                 (VkSubpassDescriptionFlags)0u,
482                 VK_PIPELINE_BIND_POINT_GRAPHICS,
483                 0u,                                                     // inputAttachmentCount
484                 DE_NULL,                                        // pInputAttachments
485                 1u,                                                     // colorAttachmentCount
486                 &colorAttRef,                           // pColorAttachments
487                 DE_NULL,                                        // pResolveAttachments
488                 DE_NULL,                                        // depthStencilAttachment
489                 0u,                                                     // preserveAttachmentCount
490                 DE_NULL,                                        // pPreserveAttachments
491         };
492         const VkSubpassDependency               dependencies[]          =
493         {
494                 {
495                         VK_SUBPASS_EXTERNAL,    // srcSubpass
496                         0u,                                             // dstSubpass
497                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
498                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
499                         VK_ACCESS_MEMORY_READ_BIT,
500                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
501                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
502                         VK_DEPENDENCY_BY_REGION_BIT
503                 },
504                 {
505                         0u,                                             // srcSubpass
506                         VK_SUBPASS_EXTERNAL,    // dstSubpass
507                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
508                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
509                         (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
510                          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
511                         VK_ACCESS_MEMORY_READ_BIT,
512                         VK_DEPENDENCY_BY_REGION_BIT
513                 },
514         };
515         const VkRenderPassCreateInfo    renderPassParams        =
516         {
517                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
518                 DE_NULL,
519                 (VkRenderPassCreateFlags)0,
520                 1u,
521                 &colorAttDesc,
522                 1u,
523                 &subpassDesc,
524                 DE_LENGTH_OF_ARRAY(dependencies),
525                 dependencies,
526         };
527
528         return vk::createRenderPass(vkd, device, &renderPassParams);
529 }
530
531 Move<VkPipelineLayout> TriangleRenderer::createPipelineLayout (const DeviceInterface&   vkd,
532                                                                                                                            const VkDevice                       device)
533 {
534         const VkPushConstantRange                                               pushConstantRange               =
535         {
536                 VK_SHADER_STAGE_VERTEX_BIT,
537                 0u,                                                                                     // offset
538                 (deUint32)sizeof(deUint32),                                     // size
539         };
540         const VkPipelineLayoutCreateInfo                                pipelineLayoutParams    =
541         {
542                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
543                 DE_NULL,
544                 (vk::VkPipelineLayoutCreateFlags)0,
545                 0u,                                                                                     // setLayoutCount
546                 DE_NULL,                                                                        // pSetLayouts
547                 1u,
548                 &pushConstantRange,
549         };
550
551         return vk::createPipelineLayout(vkd, device, &pipelineLayoutParams);
552 }
553
554 Move<VkPipeline> TriangleRenderer::createPipeline (const DeviceInterface&       vkd,
555                                                                                                    const VkDevice                       device,
556                                                                                                    const VkRenderPass           renderPass,
557                                                                                                    const VkPipelineLayout       pipelineLayout,
558                                                                                                    const BinaryCollection&      binaryCollection,
559                                                                                                    const UVec2&                         renderSize)
560 {
561         // \note VkShaderModules are fully consumed by vkCreateGraphicsPipelines()
562         //               and can be deleted immediately following that call.
563         const Unique<VkShaderModule>                                    vertShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-vert"), 0));
564         const Unique<VkShaderModule>                                    fragShaderModule                (createShaderModule(vkd, device, binaryCollection.get("tri-frag"), 0));
565         const std::vector<VkViewport>                                   viewports                               (1, makeViewport(renderSize));
566         const std::vector<VkRect2D>                                             scissors                                (1, makeRect2D(renderSize));
567
568         return vk::makeGraphicsPipeline(vkd,                            // const DeviceInterface&            vk
569                                                                         device,                         // const VkDevice                    device
570                                                                         pipelineLayout,         // const VkPipelineLayout            pipelineLayout
571                                                                         *vertShaderModule,      // const VkShaderModule              vertexShaderModule
572                                                                         DE_NULL,                        // const VkShaderModule              tessellationControlShaderModule
573                                                                         DE_NULL,                        // const VkShaderModule              tessellationEvalShaderModule
574                                                                         DE_NULL,                        // const VkShaderModule              geometryShaderModule
575                                                                         *fragShaderModule,      // const VkShaderModule              fragmentShaderModule
576                                                                         renderPass,                     // const VkRenderPass                renderPass
577                                                                         viewports,                      // const std::vector<VkViewport>&    viewports
578                                                                         scissors);                      // const std::vector<VkRect2D>&      scissors
579 }
580
581 Move<VkImageView> TriangleRenderer::createAttachmentView (const DeviceInterface&        vkd,
582                                                                                                                   const VkDevice                        device,
583                                                                                                                   const VkImage                         image,
584                                                                                                                   const VkFormat                        format)
585 {
586         const VkImageViewCreateInfo             viewParams      =
587         {
588                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
589                 DE_NULL,
590                 (VkImageViewCreateFlags)0,
591                 image,
592                 VK_IMAGE_VIEW_TYPE_2D,
593                 format,
594                 vk::makeComponentMappingRGBA(),
595                 {
596                         VK_IMAGE_ASPECT_COLOR_BIT,
597                         0u,                                             // baseMipLevel
598                         1u,                                             // levelCount
599                         0u,                                             // baseArrayLayer
600                         1u,                                             // layerCount
601                 },
602         };
603
604         return vk::createImageView(vkd, device, &viewParams);
605 }
606
607 Move<VkFramebuffer> TriangleRenderer::createFramebuffer (const DeviceInterface&         vkd,
608                                                                                                                  const VkDevice                         device,
609                                                                                                                  const VkRenderPass                     renderPass,
610                                                                                                                  const VkImageView                      colorAttachment,
611                                                                                                                  const UVec2&                           renderSize)
612 {
613         const VkFramebufferCreateInfo   framebufferParams       =
614         {
615                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
616                 DE_NULL,
617                 (VkFramebufferCreateFlags)0,
618                 renderPass,
619                 1u,
620                 &colorAttachment,
621                 renderSize.x(),
622                 renderSize.y(),
623                 1u,                                                     // layers
624         };
625
626         return vk::createFramebuffer(vkd, device, &framebufferParams);
627 }
628
629 Move<VkBuffer> TriangleRenderer::createBuffer (const DeviceInterface&   vkd,
630                                                                                            VkDevice                                     device,
631                                                                                            VkDeviceSize                         size,
632                                                                                            VkBufferUsageFlags           usage)
633 {
634         const VkBufferCreateInfo        bufferParams    =
635         {
636                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
637                 DE_NULL,
638                 (VkBufferCreateFlags)0,
639                 size,
640                 usage,
641                 VK_SHARING_MODE_EXCLUSIVE,
642                 0,
643                 DE_NULL
644         };
645
646         return vk::createBuffer(vkd, device, &bufferParams);
647 }
648
649 TriangleRenderer::TriangleRenderer (const DeviceInterface&      vkd,
650                                                                         const VkDevice                  device,
651                                                                         Allocator&                              allocator,
652                                                                         const BinaryCollection& binaryRegistry,
653                                                                         const vector<VkImage>   swapchainImages,
654                                                                         const VkFormat                  framebufferFormat,
655                                                                         const UVec2&                    renderSize)
656         : m_vkd                                 (vkd)
657         , m_swapchainImages             (swapchainImages)
658         , m_renderSize                  (renderSize)
659         , m_renderPass                  (createRenderPass(vkd, device, framebufferFormat))
660         , m_pipelineLayout              (createPipelineLayout(vkd, device))
661         , m_pipeline                    (createPipeline(vkd, device, *m_renderPass, *m_pipelineLayout, binaryRegistry, renderSize))
662         , m_vertexBuffer                (createBuffer(vkd, device, (VkDeviceSize)(sizeof(float)*4*3), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))
663         , m_vertexBufferMemory  (allocator.allocate(getBufferMemoryRequirements(vkd, device, *m_vertexBuffer),
664                                                          MemoryRequirement::HostVisible))
665 {
666         m_attachmentViews.resize(swapchainImages.size());
667         m_framebuffers.resize(swapchainImages.size());
668
669         for (size_t imageNdx = 0; imageNdx < swapchainImages.size(); ++imageNdx)
670         {
671                 m_attachmentViews[imageNdx]     = ImageViewSp(new Unique<VkImageView>(createAttachmentView(vkd, device, swapchainImages[imageNdx], framebufferFormat)));
672                 m_framebuffers[imageNdx]        = FramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(vkd, device, *m_renderPass, **m_attachmentViews[imageNdx], renderSize)));
673         }
674
675         VK_CHECK(vkd.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
676
677         {
678                 const VkMappedMemoryRange       memRange        =
679                 {
680                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
681                         DE_NULL,
682                         m_vertexBufferMemory->getMemory(),
683                         m_vertexBufferMemory->getOffset(),
684                         VK_WHOLE_SIZE
685                 };
686                 const tcu::Vec4                         vertices[]      =
687                 {
688                         tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
689                         tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
690                         tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
691                 };
692                 DE_STATIC_ASSERT(sizeof(vertices) == sizeof(float)*4*3);
693
694                 deMemcpy(m_vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
695                 VK_CHECK(vkd.flushMappedMemoryRanges(device, 1u, &memRange));
696         }
697 }
698
699 TriangleRenderer::~TriangleRenderer (void)
700 {
701 }
702
703 void TriangleRenderer::recordFrame (VkCommandBuffer     cmdBuffer,
704                                                                         deUint32                imageNdx,
705                                                                         deUint32                frameNdx) const
706 {
707         const VkFramebuffer     curFramebuffer  = **m_framebuffers[imageNdx];
708
709         beginCommandBuffer(m_vkd, cmdBuffer, 0u);
710
711         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));
712
713         m_vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
714
715         {
716                 const VkDeviceSize bindingOffset = 0;
717                 m_vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
718         }
719
720         m_vkd.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, (deUint32)sizeof(deUint32), &frameNdx);
721         m_vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
722         endRenderPass(m_vkd, cmdBuffer);
723
724         endCommandBuffer(m_vkd, cmdBuffer);
725 }
726
727 void TriangleRenderer::getPrograms (SourceCollections& dst)
728 {
729         dst.glslSources.add("tri-vert") << glu::VertexSource(
730                 "#version 310 es\n"
731                 "layout(location = 0) in highp vec4 a_position;\n"
732                 "layout(push_constant) uniform FrameData\n"
733                 "{\n"
734                 "    highp uint frameNdx;\n"
735                 "} frameData;\n"
736                 "void main (void)\n"
737                 "{\n"
738                 "    highp float angle = float(frameData.frameNdx) / 100.0;\n"
739                 "    highp float c     = cos(angle);\n"
740                 "    highp float s     = sin(angle);\n"
741                 "    highp mat4  t     = mat4( c, -s,  0,  0,\n"
742                 "                              s,  c,  0,  0,\n"
743                 "                              0,  0,  1,  0,\n"
744                 "                              0,  0,  0,  1);\n"
745                 "    gl_Position = t * a_position;\n"
746                 "}\n");
747         dst.glslSources.add("tri-frag") << glu::FragmentSource(
748                 "#version 310 es\n"
749                 "layout(location = 0) out lowp vec4 o_color;\n"
750                 "void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
751 }
752
753 typedef de::SharedPtr<Unique<VkCommandBuffer> > CommandBufferSp;
754 typedef de::SharedPtr<Unique<VkFence> >                 FenceSp;
755 typedef de::SharedPtr<Unique<VkSemaphore> >             SemaphoreSp;
756
757 vector<FenceSp> createFences (const DeviceInterface&    vkd,
758                                                           const VkDevice                        device,
759                                                           size_t                                        numFences)
760 {
761         vector<FenceSp> fences(numFences);
762
763         for (size_t ndx = 0; ndx < numFences; ++ndx)
764                 fences[ndx] = FenceSp(new Unique<VkFence>(createFence(vkd, device)));
765
766         return fences;
767 }
768
769 vector<SemaphoreSp> createSemaphores (const DeviceInterface&    vkd,
770                                                                           const VkDevice                        device,
771                                                                           size_t                                        numSemaphores)
772 {
773         vector<SemaphoreSp> semaphores(numSemaphores);
774
775         for (size_t ndx = 0; ndx < numSemaphores; ++ndx)
776                 semaphores[ndx] = SemaphoreSp(new Unique<VkSemaphore>(createSemaphore(vkd, device)));
777
778         return semaphores;
779 }
780
781 vector<CommandBufferSp> allocateCommandBuffers (const DeviceInterface&          vkd,
782                                                                                                 const VkDevice                          device,
783                                                                                                 const VkCommandPool                     commandPool,
784                                                                                                 const VkCommandBufferLevel      level,
785                                                                                                 const size_t                            numCommandBuffers)
786 {
787         vector<CommandBufferSp>                         buffers         (numCommandBuffers);
788
789         for (size_t ndx = 0; ndx < numCommandBuffers; ++ndx)
790                 buffers[ndx] = CommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(vkd, device, commandPool, level)));
791
792         return buffers;
793 }
794
795 tcu::TestStatus basicExtensionTest (Context& context, Type wsiType)
796 {
797         const tcu::UVec2                                desiredSize             (256, 256);
798         const InstanceHelper                    instHelper              (context, wsiType);
799         const NativeObjects                             native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
800         const Unique<VkSurfaceKHR>              surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
801         const DeviceHelper                              devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
802
803         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
804                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
805
806         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
807                                                                                                                                                                                   devHelper.physicalDevice,
808                                                                                                                                                                                   *surface);
809
810         bool found = false;
811         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
812         {
813                 if (curFmt->colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
814                 {
815                         found = true;
816                         break;
817                 }
818         }
819         if (!found)
820         {
821                 TCU_THROW(NotSupportedError, "VK_EXT_swapchain_colorspace supported, but no non-SRGB_NONLINEAR_KHR surface formats found.");
822         }
823         return tcu::TestStatus::pass("Extension tests succeeded");
824 }
825
826 tcu::TestStatus surfaceFormatRenderTest (Context& context,
827                                                                                  Type wsiType,
828                                                                                  VkSurfaceKHR surface,
829                                                                                  VkSurfaceFormatKHR curFmt,
830                                                                                  deBool checkHdr = false)
831 {
832         const tcu::UVec2                                        desiredSize             (256, 256);
833         const InstanceHelper                            instHelper              (context, wsiType);
834         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, surface);
835         const DeviceInterface&                          vkd                             = devHelper.vkd;
836         const VkDevice                                          device                  = *devHelper.device;
837         SimpleAllocator                                         allocator               (vkd, device, getPhysicalDeviceMemoryProperties(instHelper.vki, devHelper.physicalDevice));
838
839         const VkSwapchainCreateInfoKHR          swapchainInfo                   = getBasicSwapchainParameters(wsiType, instHelper.vki, devHelper.physicalDevice, surface, curFmt, desiredSize, 2);
840         const Unique<VkSwapchainKHR>            swapchain                               (createSwapchainKHR(vkd, device, &swapchainInfo));
841         const vector<VkImage>                           swapchainImages                 = getSwapchainImages(vkd, device, *swapchain);
842         const vector<VkExtensionProperties>     deviceExtensions                (enumerateDeviceExtensionProperties(instHelper.vki, devHelper.physicalDevice, DE_NULL));
843
844         if (checkHdr && !isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_hdr_metadata")))
845                 TCU_THROW(NotSupportedError, "Extension VK_EXT_hdr_metadata not supported");
846
847         const TriangleRenderer                  renderer                                        (vkd,
848                                                                                                                                  device,
849                                                                                                                                  allocator,
850                                                                                                                                  context.getBinaryCollection(),
851                                                                                                                                  swapchainImages,
852                                                                                                                                  swapchainInfo.imageFormat,
853                                                                                                                                  tcu::UVec2(swapchainInfo.imageExtent.width, swapchainInfo.imageExtent.height));
854
855         const Unique<VkCommandPool>             commandPool                                     (createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, devHelper.queueFamilyIndex));
856
857         const size_t                                    maxQueuedFrames                         = swapchainImages.size()*2;
858
859         // We need to keep hold of fences from vkAcquireNextImageKHR to actually
860         // limit number of frames we allow to be queued.
861         const vector<FenceSp>                   imageReadyFences                        (createFences(vkd, device, maxQueuedFrames));
862
863         // We need maxQueuedFrames+1 for imageReadySemaphores pool as we need to pass
864         // the semaphore in same time as the fence we use to meter rendering.
865         const vector<SemaphoreSp>               imageReadySemaphores            (createSemaphores(vkd, device, maxQueuedFrames+1));
866
867         // For rest we simply need maxQueuedFrames as we will wait for image
868         // from frameNdx-maxQueuedFrames to become available to us, guaranteeing that
869         // previous uses must have completed.
870         const vector<SemaphoreSp>               renderingCompleteSemaphores     (createSemaphores(vkd, device, maxQueuedFrames));
871         const vector<CommandBufferSp>   commandBuffers                          (allocateCommandBuffers(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, maxQueuedFrames));
872
873         try
874         {
875                 const deUint32  numFramesToRender       = 60;
876
877                 for (deUint32 frameNdx = 0; frameNdx < numFramesToRender; ++frameNdx)
878                 {
879                         const VkFence           imageReadyFence         = **imageReadyFences[frameNdx%imageReadyFences.size()];
880                         const VkSemaphore       imageReadySemaphore     = **imageReadySemaphores[frameNdx%imageReadySemaphores.size()];
881                         deUint32                        imageNdx                        = ~0u;
882
883                         if (frameNdx >= maxQueuedFrames)
884                                 VK_CHECK(vkd.waitForFences(device, 1u, &imageReadyFence, VK_TRUE, std::numeric_limits<deUint64>::max()));
885
886                         VK_CHECK(vkd.resetFences(device, 1, &imageReadyFence));
887
888                         {
889                                 const VkResult  acquireResult   = vkd.acquireNextImageKHR(device,
890                                                                                                                                                   *swapchain,
891                                                                                                                                                   std::numeric_limits<deUint64>::max(),
892                                                                                                                                                   imageReadySemaphore,
893                                                                                                                                                   (vk::VkFence)0,
894                                                                                                                                                   &imageNdx);
895
896                                 if (acquireResult == VK_SUBOPTIMAL_KHR)
897                                         context.getTestContext().getLog() << TestLog::Message << "Got " << acquireResult << " at frame " << frameNdx << TestLog::EndMessage;
898                                 else
899                                         VK_CHECK(acquireResult);
900                         }
901
902                         TCU_CHECK((size_t)imageNdx < swapchainImages.size());
903
904                         {
905                                 const VkSemaphore                       renderingCompleteSemaphore      = **renderingCompleteSemaphores[frameNdx%renderingCompleteSemaphores.size()];
906                                 const VkCommandBuffer           commandBuffer                           = **commandBuffers[frameNdx%commandBuffers.size()];
907                                 const VkPipelineStageFlags      waitDstStage                            = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
908                                 const VkSubmitInfo                      submitInfo                                      =
909                                 {
910                                         VK_STRUCTURE_TYPE_SUBMIT_INFO,
911                                         DE_NULL,
912                                         1u,
913                                         &imageReadySemaphore,
914                                         &waitDstStage,
915                                         1u,
916                                         &commandBuffer,
917                                         1u,
918                                         &renderingCompleteSemaphore
919                                 };
920                                 const VkPresentInfoKHR          presentInfo                                     =
921                                 {
922                                         VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
923                                         DE_NULL,
924                                         1u,
925                                         &renderingCompleteSemaphore,
926                                         1u,
927                                         &*swapchain,
928                                         &imageNdx,
929                                         (VkResult*)DE_NULL
930                                 };
931
932                                 if (checkHdr) {
933                                         const VkHdrMetadataEXT hdrData = {
934                                                         VK_STRUCTURE_TYPE_HDR_METADATA_EXT,
935                                                         DE_NULL,
936                                                         makeXYColorEXT(0.680f, 0.320f),
937                                                         makeXYColorEXT(0.265f, 0.690f),
938                                                         makeXYColorEXT(0.150f, 0.060f),
939                                                         makeXYColorEXT(0.3127f, 0.3290f),
940                                                         1000.0,
941                                                         0.0,
942                                                         1000.0,
943                                                         70.0
944                                         };
945                                         vector<VkSwapchainKHR> swapchainArray;
946
947                                         swapchainArray.push_back(*swapchain);
948                                         vkd.setHdrMetadataEXT(device, (deUint32)swapchainArray.size(), swapchainArray.data(), &hdrData);
949                                 }
950
951                                 renderer.recordFrame(commandBuffer, imageNdx, frameNdx);
952                                 VK_CHECK(vkd.queueSubmit(devHelper.queue, 1u, &submitInfo, imageReadyFence));
953                                 VK_CHECK(vkd.queuePresentKHR(devHelper.queue, &presentInfo));
954                         }
955                 }
956
957                 VK_CHECK(vkd.deviceWaitIdle(device));
958         }
959         catch (...)
960         {
961                 // Make sure device is idle before destroying resources
962                 vkd.deviceWaitIdle(device);
963                 throw;
964         }
965
966         return tcu::TestStatus::pass("Rendering test succeeded");
967 }
968
969 tcu::TestStatus surfaceFormatRenderTests (Context& context, Type wsiType)
970 {
971         const tcu::UVec2                                        desiredSize             (256, 256);
972         const InstanceHelper                            instHelper              (context, wsiType);
973         const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
974         const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
975         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
976
977         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
978                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
979
980         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
981                                                                                                                                                                                          devHelper.physicalDevice,
982                                                                                                                                                                                          *surface);
983         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
984         {
985                 surfaceFormatRenderTest(context, wsiType, *surface, *curFmt);
986         }
987         return tcu::TestStatus::pass("Rendering tests succeeded");
988 }
989
990 tcu::TestStatus surfaceFormatRenderWithHdrTests (Context& context, Type wsiType)
991 {
992         const tcu::UVec2                                        desiredSize             (256, 256);
993         const InstanceHelper                            instHelper              (context, wsiType);
994         const NativeObjects                                     native                  (context, instHelper.supportedExtensions, wsiType, tcu::just(desiredSize));
995         const Unique<VkSurfaceKHR>                      surface                 (createSurface(instHelper.vki, *instHelper.instance, wsiType, *native.display, *native.window));
996         const DeviceHelper                                      devHelper               (context, instHelper.vki, *instHelper.instance, *surface);
997
998         if (!de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_EXT_swapchain_colorspace"))
999                 TCU_THROW(NotSupportedError, "Extension VK_EXT_swapchain_colorspace not supported");
1000
1001         const vector<VkSurfaceFormatKHR>        formats                 = getPhysicalDeviceSurfaceFormats(instHelper.vki,
1002                                                                                                                                                                                   devHelper.physicalDevice,
1003                                                                                                                                                                                   *surface);
1004         for (vector<VkSurfaceFormatKHR>::const_iterator curFmt = formats.begin(); curFmt != formats.end(); ++curFmt)
1005         {
1006                 surfaceFormatRenderTest(context, wsiType, *surface, *curFmt, true);
1007         }
1008         return tcu::TestStatus::pass("Rendering tests succeeded");
1009 }
1010
1011 void getBasicRenderPrograms (SourceCollections& dst, Type)
1012 {
1013         TriangleRenderer::getPrograms(dst);
1014 }
1015
1016 } // anonymous
1017
1018 void createColorSpaceTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1019 {
1020         addFunctionCase(testGroup, "extensions", "Verify Colorspace Extensions", basicExtensionTest, wsiType);
1021         addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Tests", getBasicRenderPrograms, surfaceFormatRenderTests, wsiType);
1022         addFunctionCaseWithPrograms(testGroup, "hdr", "Basic Rendering Tests with HDR", getBasicRenderPrograms, surfaceFormatRenderWithHdrTests, wsiType);
1023 }
1024
1025 } // wsi
1026 } // vkt