1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Tests for incremental present extension
22 *//*--------------------------------------------------------------------*/
24 #include "vktWsiIncrementalPresentTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkWsiPlatform.hpp"
30 #include "vkWsiUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkDeviceUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkPrograms.hpp"
37 #include "vkWsiUtil.hpp"
39 #include "tcuPlatform.hpp"
40 #include "tcuResultCollector.hpp"
41 #include "tcuTestLog.hpp"
66 typedef vector<vk::VkExtensionProperties> Extensions;
68 void checkAllSupported (const Extensions& supportedExtensions, const vector<string>& requiredExtensions)
70 for (vector<string>::const_iterator requiredExtName = requiredExtensions.begin();
71 requiredExtName != requiredExtensions.end();
74 if (!isExtensionSupported(supportedExtensions, vk::RequiredExtension(*requiredExtName)))
75 TCU_THROW(NotSupportedError, (*requiredExtName + " is not supported").c_str());
79 vk::Move<vk::VkInstance> createInstanceWithWsi (const vk::PlatformInterface& vkp,
80 const Extensions& supportedExtensions,
81 vk::wsi::Type wsiType)
83 vector<string> extensions;
85 extensions.push_back("VK_KHR_surface");
86 extensions.push_back(getExtensionName(wsiType));
88 checkAllSupported(supportedExtensions, extensions);
90 return vk::createDefaultInstance(vkp, vector<string>(), extensions);
93 vk::VkPhysicalDeviceFeatures getDeviceNullFeatures (void)
95 vk::VkPhysicalDeviceFeatures features;
96 deMemset(&features, 0, sizeof(features));
100 deUint32 getNumQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice)
102 deUint32 numFamilies = 0;
104 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
109 vector<deUint32> getSupportedQueueFamilyIndices (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
111 const deUint32 numTotalFamilyIndices = getNumQueueFamilyIndices(vki, physicalDevice);
112 vector<deUint32> supportedFamilyIndices;
114 for (deUint32 queueFamilyNdx = 0; queueFamilyNdx < numTotalFamilyIndices; ++queueFamilyNdx)
116 if (vk::wsi::getPhysicalDeviceSurfaceSupport(vki, physicalDevice, queueFamilyNdx, surface) != VK_FALSE)
117 supportedFamilyIndices.push_back(queueFamilyNdx);
120 return supportedFamilyIndices;
123 deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface& vki, vk::VkPhysicalDevice physicalDevice, vk::VkSurfaceKHR surface)
125 const vector<deUint32> supportedFamilyIndices = getSupportedQueueFamilyIndices(vki, physicalDevice, surface);
127 if (supportedFamilyIndices.empty())
128 TCU_THROW(NotSupportedError, "Device doesn't support presentation");
130 return supportedFamilyIndices[0];
133 vk::Move<vk::VkDevice> createDeviceWithWsi (const vk::InstanceInterface& vki,
134 vk::VkPhysicalDevice physicalDevice,
135 const Extensions& supportedExtensions,
136 const deUint32 queueFamilyIndex,
137 bool requiresIncrementalPresent,
138 const vk::VkAllocationCallbacks* pAllocator = DE_NULL)
140 const float queuePriorities[] = { 1.0f };
141 const vk::VkDeviceQueueCreateInfo queueInfos[] =
144 vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
146 (vk::VkDeviceQueueCreateFlags)0,
148 DE_LENGTH_OF_ARRAY(queuePriorities),
152 const vk::VkPhysicalDeviceFeatures features = getDeviceNullFeatures();
153 const char* const extensions[] =
156 "VK_KHR_incremental_present"
159 const vk::VkDeviceCreateInfo deviceParams =
161 vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
163 (vk::VkDeviceCreateFlags)0,
164 DE_LENGTH_OF_ARRAY(queueInfos),
168 requiresIncrementalPresent ? 2u : 1u,
169 DE_ARRAY_BEGIN(extensions),
173 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(extensions); ++ndx)
175 if (!isExtensionSupported(supportedExtensions, vk::RequiredExtension(extensions[ndx])))
176 TCU_THROW(NotSupportedError, (string(extensions[ndx]) + " is not supported").c_str());
179 return createDevice(vki, physicalDevice, &deviceParams, pAllocator);
182 de::MovePtr<vk::wsi::Display> createDisplay (const vk::Platform& platform,
183 const Extensions& supportedExtensions,
184 vk::wsi::Type wsiType)
188 return de::MovePtr<vk::wsi::Display>(platform.createWsiDisplay(wsiType));
190 catch (const tcu::NotSupportedError& e)
192 if (isExtensionSupported(supportedExtensions, vk::RequiredExtension(getExtensionName(wsiType))))
194 // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
195 // must support creating native display & window for that WSI type.
196 throw tcu::TestError(e.getMessage());
203 de::MovePtr<vk::wsi::Window> createWindow (const vk::wsi::Display& display, const Maybe<UVec2>& initialSize)
207 return de::MovePtr<vk::wsi::Window>(display.createWindow(initialSize));
209 catch (const tcu::NotSupportedError& e)
211 // See createDisplay - assuming that wsi::Display was supported platform port
212 // should also support creating a window.
213 throw tcu::TestError(e.getMessage());
217 void initSemaphores (const vk::DeviceInterface& vkd,
219 std::vector<vk::VkSemaphore>& semaphores)
221 for (size_t ndx = 0; ndx < semaphores.size(); ndx++)
222 semaphores[ndx] = createSemaphore(vkd, device).disown();
225 void deinitSemaphores (const vk::DeviceInterface& vkd,
227 std::vector<vk::VkSemaphore>& semaphores)
229 for (size_t ndx = 0; ndx < semaphores.size(); ndx++)
231 if (semaphores[ndx] != (vk::VkSemaphore)0)
232 vkd.destroySemaphore(device, semaphores[ndx], DE_NULL);
234 semaphores[ndx] = (vk::VkSemaphore)0;
240 void initFences (const vk::DeviceInterface& vkd,
242 std::vector<vk::VkFence>& fences)
244 for (size_t ndx = 0; ndx < fences.size(); ndx++)
245 fences[ndx] = createFence(vkd, device).disown();
248 void deinitFences (const vk::DeviceInterface& vkd,
250 std::vector<vk::VkFence>& fences)
252 for (size_t ndx = 0; ndx < fences.size(); ndx++)
254 if (fences[ndx] != (vk::VkFence)0)
255 vkd.destroyFence(device, fences[ndx], DE_NULL);
257 fences[ndx] = (vk::VkFence)0;
263 vk::VkRect2D getRenderFrameRect (size_t frameNdx,
265 deUint32 imageHeight)
267 const deUint32 x = frameNdx == 0
269 : de::min(((deUint32)frameNdx) % imageWidth, imageWidth - 1u);
270 const deUint32 y = frameNdx == 0
272 : de::min(((deUint32)frameNdx) % imageHeight, imageHeight - 1u);
273 const deUint32 width = frameNdx == 0
275 : 1 + de::min((deUint32)(frameNdx) % de::min<deUint32>(100, imageWidth / 3), imageWidth - x);
276 const deUint32 height = frameNdx == 0
278 : 1 + de::min((deUint32)(frameNdx) % de::min<deUint32>(100, imageHeight / 3), imageHeight - y);
279 const vk::VkRect2D rect =
281 { (deInt32)x, (deInt32)y },
285 DE_ASSERT(width > 0);
286 DE_ASSERT(height > 0);
291 vector<vk::VkRectLayerKHR> getUpdatedRects (size_t firstFrameNdx,
296 vector<vk::VkRectLayerKHR> rects;
298 for (size_t frameNdx = firstFrameNdx; frameNdx <= lastFrameNdx; frameNdx++)
300 const vk::VkRect2D rect = getRenderFrameRect(frameNdx, width, height);
301 const vk::VkRectLayerKHR rectLayer =
308 rects.push_back(rectLayer);
314 void cmdRenderFrame (const vk::DeviceInterface& vkd,
315 vk::VkCommandBuffer commandBuffer,
316 vk::VkPipelineLayout pipelineLayout,
317 vk::VkPipeline pipeline,
320 deUint32 imageHeight)
322 const deUint32 mask = (deUint32)frameNdx;
326 const vk::VkRect2D scissor =
329 { imageWidth, imageHeight }
332 vkd.cmdSetScissor(commandBuffer, 0u, 1u, &scissor);
333 const vk::VkClearAttachment attachment =
335 vk::VK_IMAGE_ASPECT_COLOR_BIT,
337 vk::makeClearValueColorF32(0.25f, 0.50, 0.75f, 1.00f)
339 const vk::VkClearRect rect =
346 vkd.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
350 const vk::VkRect2D scissor = getRenderFrameRect(frameNdx, imageWidth, imageHeight);
351 vkd.cmdSetScissor(commandBuffer, 0u, 1u, &scissor);
353 vkd.cmdPushConstants(commandBuffer, pipelineLayout, vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0u, 4u, &mask);
354 vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
355 vkd.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
359 vk::Move<vk::VkCommandBuffer> createCommandBuffer (const vk::DeviceInterface& vkd,
361 vk::VkCommandPool commandPool,
362 vk::VkPipelineLayout pipelineLayout,
363 vk::VkRenderPass renderPass,
364 vk::VkFramebuffer framebuffer,
365 vk::VkPipeline pipeline,
368 size_t imageNextFrame,
371 deUint32 imageHeight)
373 const vk::VkCommandBufferAllocateInfo allocateInfo =
375 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
379 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,
382 const vk::VkCommandBufferBeginInfo beginInfo =
384 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
390 vk::Move<vk::VkCommandBuffer> commandBuffer (vk::allocateCommandBuffer(vkd, device, &allocateInfo));
391 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &beginInfo));
394 const vk::VkImageSubresourceRange subRange =
396 vk::VK_IMAGE_ASPECT_COLOR_BIT,
402 const vk::VkImageMemoryBarrier barrier =
404 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
406 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
407 vk::VK_ACCESS_TRANSFER_READ_BIT | vk::VK_ACCESS_TRANSFER_WRITE_BIT,
408 isFirst ? vk::VK_IMAGE_LAYOUT_UNDEFINED : vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
409 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
410 VK_QUEUE_FAMILY_IGNORED,
411 VK_QUEUE_FAMILY_IGNORED,
415 vkd.cmdPipelineBarrier(*commandBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &barrier);
419 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.25f, 0.50f, 0.75f, 1.00f);
420 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
422 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
429 { (deInt32)0, (deInt32)0 },
430 { imageWidth, imageHeight }
435 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, vk::VK_SUBPASS_CONTENTS_INLINE);
438 for (size_t frameNdx = imageNextFrame; frameNdx <= currentFrame; frameNdx++)
439 cmdRenderFrame(vkd, *commandBuffer, pipelineLayout, pipeline, frameNdx, imageWidth, imageHeight);
441 vkd.cmdEndRenderPass(*commandBuffer);
443 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
444 return commandBuffer;
447 void deinitCommandBuffers (const vk::DeviceInterface& vkd,
449 vk::VkCommandPool commandPool,
450 std::vector<vk::VkCommandBuffer>& commandBuffers)
452 for (size_t ndx = 0; ndx < commandBuffers.size(); ndx++)
454 if (commandBuffers[ndx] != (vk::VkCommandBuffer)0)
455 vkd.freeCommandBuffers(device, commandPool, 1u, &commandBuffers[ndx]);
457 commandBuffers[ndx] = (vk::VkCommandBuffer)0;
460 commandBuffers.clear();
463 vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vkd,
465 deUint32 queueFamilyIndex)
467 const vk::VkCommandPoolCreateInfo createInfo =
469 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
475 return vk::createCommandPool(vkd, device, &createInfo);
478 vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vkd,
480 vk::VkRenderPass renderPass,
481 vk::VkImageView imageView,
485 const vk::VkFramebufferCreateInfo createInfo =
487 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
499 return vk::createFramebuffer(vkd, device, &createInfo);
502 void initFramebuffers (const vk::DeviceInterface& vkd,
504 vk::VkRenderPass renderPass,
505 std::vector<vk::VkImageView> imageViews,
508 std::vector<vk::VkFramebuffer>& framebuffers)
510 DE_ASSERT(framebuffers.size() == imageViews.size());
512 for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
513 framebuffers[ndx] = createFramebuffer(vkd, device, renderPass, imageViews[ndx], width, height).disown();
516 void deinitFramebuffers (const vk::DeviceInterface& vkd,
518 std::vector<vk::VkFramebuffer>& framebuffers)
520 for (size_t ndx = 0; ndx < framebuffers.size(); ndx++)
522 if (framebuffers[ndx] != (vk::VkFramebuffer)0)
523 vkd.destroyFramebuffer(device, framebuffers[ndx], DE_NULL);
525 framebuffers[ndx] = (vk::VkFramebuffer)0;
528 framebuffers.clear();
531 vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vkd,
536 const vk::VkImageViewCreateInfo createInfo =
538 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
543 vk::VK_IMAGE_VIEW_TYPE_2D,
545 vk::makeComponentMappingRGBA(),
547 vk::VK_IMAGE_ASPECT_COLOR_BIT,
555 return vk::createImageView(vkd, device, &createInfo, DE_NULL);
558 void initImageViews (const vk::DeviceInterface& vkd,
560 const std::vector<vk::VkImage>& images,
562 std::vector<vk::VkImageView>& imageViews)
564 DE_ASSERT(images.size() == imageViews.size());
566 for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
567 imageViews[ndx] = createImageView(vkd, device, images[ndx], format).disown();
570 void deinitImageViews (const vk::DeviceInterface& vkd,
572 std::vector<vk::VkImageView>& imageViews)
574 for (size_t ndx = 0; ndx < imageViews.size(); ndx++)
576 if (imageViews[ndx] != (vk::VkImageView)0)
577 vkd.destroyImageView(device, imageViews[ndx], DE_NULL);
579 imageViews[ndx] = (vk::VkImageView)0;
585 vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vkd,
589 const vk::VkAttachmentDescription attachments[] =
594 vk::VK_SAMPLE_COUNT_1_BIT,
596 vk::VK_ATTACHMENT_LOAD_OP_LOAD,
597 vk::VK_ATTACHMENT_STORE_OP_STORE,
599 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
600 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
602 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
603 vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
606 const vk::VkAttachmentReference colorAttachmentRefs[] =
610 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
613 const vk::VkSubpassDescription subpasses[] =
617 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
621 DE_LENGTH_OF_ARRAY(colorAttachmentRefs),
631 const vk::VkRenderPassCreateInfo createInfo =
633 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
637 DE_LENGTH_OF_ARRAY(attachments),
640 DE_LENGTH_OF_ARRAY(subpasses),
647 return vk::createRenderPass(vkd, device, &createInfo);
650 vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vkd,
652 vk::VkRenderPass renderPass,
653 vk::VkPipelineLayout layout,
654 vk::VkShaderModule vertexShaderModule,
655 vk::VkShaderModule fragmentShaderModule,
659 const vk::VkSpecializationInfo shaderSpecialization =
666 const vk::VkPipelineShaderStageCreateInfo stages[] =
669 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
672 vk::VK_SHADER_STAGE_VERTEX_BIT,
675 &shaderSpecialization
678 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
681 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
682 fragmentShaderModule,
684 &shaderSpecialization
687 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
689 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
697 const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
699 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
702 vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
705 const vk::VkViewport viewports[] =
709 (float)width, (float)height,
713 const vk::VkRect2D scissors[] =
720 const vk::VkPipelineViewportStateCreateInfo viewportState =
722 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
726 DE_LENGTH_OF_ARRAY(viewports),
728 DE_LENGTH_OF_ARRAY(scissors),
731 const vk::VkPipelineRasterizationStateCreateInfo rasterizationState =
733 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
738 vk::VK_POLYGON_MODE_FILL,
739 vk::VK_CULL_MODE_NONE,
740 vk::VK_FRONT_FACE_CLOCKWISE,
747 const vk::VkSampleMask sampleMask = ~0u;
748 const vk::VkPipelineMultisampleStateCreateInfo multisampleState =
750 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
753 vk::VK_SAMPLE_COUNT_1_BIT,
760 const vk::VkPipelineDepthStencilStateCreateInfo depthStencilState =
762 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
767 vk::VK_COMPARE_OP_ALWAYS,
771 vk::VK_STENCIL_OP_KEEP,
772 vk::VK_STENCIL_OP_KEEP,
773 vk::VK_STENCIL_OP_KEEP,
774 vk::VK_COMPARE_OP_ALWAYS,
780 vk::VK_STENCIL_OP_KEEP,
781 vk::VK_STENCIL_OP_KEEP,
782 vk::VK_STENCIL_OP_KEEP,
783 vk::VK_COMPARE_OP_ALWAYS,
791 const vk::VkPipelineColorBlendAttachmentState attachmentBlendState =
794 vk::VK_BLEND_FACTOR_ONE,
795 vk::VK_BLEND_FACTOR_ZERO,
797 vk::VK_BLEND_FACTOR_ONE,
798 vk::VK_BLEND_FACTOR_ZERO,
800 (vk::VK_COLOR_COMPONENT_R_BIT|
801 vk::VK_COLOR_COMPONENT_G_BIT|
802 vk::VK_COLOR_COMPONENT_B_BIT|
803 vk::VK_COLOR_COMPONENT_A_BIT),
805 const vk::VkPipelineColorBlendStateCreateInfo blendState =
807 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
811 vk::VK_LOGIC_OP_COPY,
813 &attachmentBlendState,
814 { 0.0f, 0.0f, 0.0f, 0.0f }
816 const vk::VkDynamicState dynamicStates[] =
818 vk::VK_DYNAMIC_STATE_SCISSOR
820 const vk::VkPipelineDynamicStateCreateInfo dynamicState =
822 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
826 DE_LENGTH_OF_ARRAY(dynamicStates),
829 const vk::VkGraphicsPipelineCreateInfo createInfo =
831 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
835 DE_LENGTH_OF_ARRAY(stages),
853 return vk::createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
856 vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vkd,
859 const vk::VkPushConstantRange pushConstants[] =
862 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
867 const vk::VkPipelineLayoutCreateInfo createInfo =
869 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
876 DE_LENGTH_OF_ARRAY(pushConstants),
880 return vk::createPipelineLayout(vkd, device, &createInfo);
885 vk::wsi::Type wsiType;
887 bool useIncrementalPresent;
888 vk::VkPresentModeKHR presentMode;
891 class IncrementalPresentTestInstance : public TestInstance
894 IncrementalPresentTestInstance (Context& context, const TestConfig& testConfig);
895 ~IncrementalPresentTestInstance (void);
897 tcu::TestStatus iterate (void);
900 const TestConfig m_testConfig;
901 const bool m_useIncrementalPresent;
902 const vk::PlatformInterface& m_vkp;
903 const Extensions m_instanceExtensions;
904 const vk::Unique<vk::VkInstance> m_instance;
905 const vk::InstanceDriver m_vki;
906 const vk::VkPhysicalDevice m_physicalDevice;
907 const de::UniquePtr<vk::wsi::Display> m_nativeDisplay;
908 const de::UniquePtr<vk::wsi::Window> m_nativeWindow;
909 const vk::Unique<vk::VkSurfaceKHR> m_surface;
911 const deUint32 m_queueFamilyIndex;
912 const Extensions m_deviceExtensions;
913 const vk::Unique<vk::VkDevice> m_device;
914 const vk::DeviceDriver m_vkd;
915 const vk::VkQueue m_queue;
917 const vk::Unique<vk::VkCommandPool> m_commandPool;
918 const vk::Unique<vk::VkShaderModule> m_vertexShaderModule;
919 const vk::Unique<vk::VkShaderModule> m_fragmentShaderModule;
920 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
922 const vk::VkSurfaceCapabilitiesKHR m_surfaceProperties;
923 const vector<vk::VkSurfaceFormatKHR> m_surfaceFormats;
924 const vector<vk::VkPresentModeKHR> m_presentModes;
926 tcu::ResultCollector m_resultCollector;
928 vk::Move<vk::VkSwapchainKHR> m_swapchain;
929 std::vector<vk::VkImage> m_swapchainImages;
930 std::vector<size_t> m_imageNextFrames;
931 std::vector<bool> m_isFirst;
933 vk::Move<vk::VkRenderPass> m_renderPass;
934 vk::Move<vk::VkPipeline> m_pipeline;
936 std::vector<vk::VkImageView> m_swapchainImageViews;
937 std::vector<vk::VkFramebuffer> m_framebuffers;
938 std::vector<vk::VkCommandBuffer> m_commandBuffers;
939 std::vector<vk::VkSemaphore> m_acquireSemaphores;
940 std::vector<vk::VkSemaphore> m_renderSemaphores;
941 std::vector<vk::VkFence> m_fences;
943 vk::VkSemaphore m_freeAcquireSemaphore;
944 vk::VkSemaphore m_freeRenderSemaphore;
946 std::vector<vk::VkSwapchainCreateInfoKHR> m_swapchainConfigs;
947 size_t m_swapchainConfigNdx;
949 const size_t m_frameCount;
952 const size_t m_maxOutOfDateCount;
953 size_t m_outOfDateCount;
955 void initSwapchainResources (void);
956 void deinitSwapchainResources (void);
960 std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainConfigs (vk::VkSurfaceKHR surface,
961 deUint32 queueFamilyIndex,
963 const vk::VkSurfaceCapabilitiesKHR& properties,
964 const vector<vk::VkSurfaceFormatKHR>& formats,
965 const vector<vk::VkPresentModeKHR>& presentModes,
966 vk::VkPresentModeKHR presentMode)
968 const deUint32 imageLayers = 1u;
969 const vk::VkImageUsageFlags imageUsage = properties.supportedUsageFlags;
970 const vk::VkBool32 clipped = VK_FALSE;
971 vector<vk::VkSwapchainCreateInfoKHR> createInfos;
973 const deUint32 imageWidth = scaling == SCALING_NONE
974 ? (properties.currentExtent.width != 0xFFFFFFFFu
975 ? properties.currentExtent.width
976 : de::min(1024u, properties.minImageExtent.width + ((properties.maxImageExtent.width - properties.minImageExtent.width) / 2)))
977 : (scaling == SCALING_UP
978 ? de::max(31u, properties.minImageExtent.width)
979 : properties.maxImageExtent.width);
980 const deUint32 imageHeight = scaling == SCALING_NONE
981 ? (properties.currentExtent.height != 0xFFFFFFFFu
982 ? properties.currentExtent.height
983 : de::min(1024u, properties.minImageExtent.height + ((properties.maxImageExtent.height - properties.minImageExtent.height) / 2)))
984 : (scaling == SCALING_UP
985 ? de::max(31u, properties.minImageExtent.height)
986 : properties.maxImageExtent.height);
987 const vk::VkExtent2D imageSize = { imageWidth, imageHeight };
990 size_t presentModeNdx;
992 for (presentModeNdx = 0; presentModeNdx < presentModes.size(); presentModeNdx++)
994 if (presentModes[presentModeNdx] == presentMode)
998 if (presentModeNdx == presentModes.size())
999 TCU_THROW(NotSupportedError, "Present mode not supported");
1002 for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
1004 for (vk::VkSurfaceTransformFlagsKHR transform = 1u; transform <= properties.supportedTransforms; transform = transform << 1u)
1006 if ((properties.supportedTransforms & transform) == 0)
1009 for (vk::VkCompositeAlphaFlagsKHR alpha = 1u; alpha <= properties.supportedCompositeAlpha; alpha = alpha << 1u)
1011 if ((alpha & properties.supportedCompositeAlpha) == 0)
1014 const vk::VkSurfaceTransformFlagBitsKHR preTransform = (vk::VkSurfaceTransformFlagBitsKHR)transform;
1015 const vk::VkCompositeAlphaFlagBitsKHR compositeAlpha = (vk::VkCompositeAlphaFlagBitsKHR)alpha;
1016 const vk::VkFormat imageFormat = formats[formatNdx].format;
1017 const vk::VkColorSpaceKHR imageColorSpace = formats[formatNdx].colorSpace;
1018 const vk::VkSwapchainCreateInfoKHR createInfo =
1020 vk::VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
1024 properties.minImageCount,
1030 vk::VK_SHARING_MODE_EXCLUSIVE,
1037 (vk::VkSwapchainKHR)0
1040 createInfos.push_back(createInfo);
1048 IncrementalPresentTestInstance::IncrementalPresentTestInstance (Context& context, const TestConfig& testConfig)
1049 : TestInstance (context)
1050 , m_testConfig (testConfig)
1051 , m_useIncrementalPresent (testConfig.useIncrementalPresent)
1052 , m_vkp (context.getPlatformInterface())
1053 , m_instanceExtensions (vk::enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
1054 , m_instance (createInstanceWithWsi(m_vkp, m_instanceExtensions, testConfig.wsiType))
1055 , m_vki (m_vkp, *m_instance)
1056 , m_physicalDevice (vk::chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
1057 , m_nativeDisplay (createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), m_instanceExtensions, testConfig.wsiType))
1058 , m_nativeWindow (createWindow(*m_nativeDisplay, tcu::nothing<UVec2>()))
1059 , m_surface (vk::wsi::createSurface(m_vki, *m_instance, testConfig.wsiType, *m_nativeDisplay, *m_nativeWindow))
1061 , m_queueFamilyIndex (chooseQueueFamilyIndex(m_vki, m_physicalDevice, *m_surface))
1062 , m_deviceExtensions (vk::enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
1063 , m_device (createDeviceWithWsi(m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex, testConfig.useIncrementalPresent))
1064 , m_vkd (m_vki, *m_device)
1065 , m_queue (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
1067 , m_commandPool (createCommandPool(m_vkd, *m_device, m_queueFamilyIndex))
1068 , m_vertexShaderModule (vk::createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-vert"), 0u))
1069 , m_fragmentShaderModule (vk::createShaderModule(m_vkd, *m_device, context.getBinaryCollection().get("quad-frag"), 0u))
1070 , m_pipelineLayout (createPipelineLayout(m_vkd, *m_device))
1072 , m_surfaceProperties (vk::wsi::getPhysicalDeviceSurfaceCapabilities(m_vki, m_physicalDevice, *m_surface))
1073 , m_surfaceFormats (vk::wsi::getPhysicalDeviceSurfaceFormats(m_vki, m_physicalDevice, *m_surface))
1074 , m_presentModes (vk::wsi::getPhysicalDeviceSurfacePresentModes(m_vki, m_physicalDevice, *m_surface))
1076 , m_freeAcquireSemaphore ((vk::VkSemaphore)0)
1077 , m_freeRenderSemaphore ((vk::VkSemaphore)0)
1079 , m_swapchainConfigs (generateSwapchainConfigs(*m_surface, m_queueFamilyIndex, testConfig.scaling, m_surfaceProperties, m_surfaceFormats, m_presentModes, testConfig.presentMode))
1080 , m_swapchainConfigNdx (0u)
1082 , m_frameCount (60u * 5u)
1085 , m_maxOutOfDateCount (20u)
1086 , m_outOfDateCount (0u)
1089 const tcu::ScopedLogSection surfaceInfo (m_context.getTestContext().getLog(), "SurfaceCapabilities", "SurfaceCapabilities");
1090 m_context.getTestContext().getLog() << TestLog::Message << m_surfaceProperties << TestLog::EndMessage;
1094 IncrementalPresentTestInstance::~IncrementalPresentTestInstance (void)
1096 deinitSwapchainResources();
1099 void IncrementalPresentTestInstance::initSwapchainResources (void)
1101 const size_t fenceCount = 6;
1102 const deUint32 imageWidth = m_swapchainConfigs[m_swapchainConfigNdx].imageExtent.width;
1103 const deUint32 imageHeight = m_swapchainConfigs[m_swapchainConfigNdx].imageExtent.height;
1104 const vk::VkFormat imageFormat = m_swapchainConfigs[m_swapchainConfigNdx].imageFormat;
1106 m_swapchain = vk::createSwapchainKHR(m_vkd, *m_device, &m_swapchainConfigs[m_swapchainConfigNdx]);
1107 m_swapchainImages = vk::wsi::getSwapchainImages(m_vkd, *m_device, *m_swapchain);
1109 m_imageNextFrames.resize(m_swapchainImages.size(), 0);
1110 m_isFirst.resize(m_swapchainImages.size(), true);
1112 m_renderPass = createRenderPass(m_vkd, *m_device, imageFormat);
1113 m_pipeline = createPipeline(m_vkd, *m_device, *m_renderPass, *m_pipelineLayout, *m_vertexShaderModule, *m_fragmentShaderModule, imageWidth, imageHeight);
1115 m_swapchainImageViews = std::vector<vk::VkImageView>(m_swapchainImages.size(), (vk::VkImageView)0);
1116 m_framebuffers = std::vector<vk::VkFramebuffer>(m_swapchainImages.size(), (vk::VkFramebuffer)0);
1117 m_acquireSemaphores = std::vector<vk::VkSemaphore>(m_swapchainImages.size(), (vk::VkSemaphore)0);
1118 m_renderSemaphores = std::vector<vk::VkSemaphore>(m_swapchainImages.size(), (vk::VkSemaphore)0);
1120 m_fences = std::vector<vk::VkFence>(fenceCount, (vk::VkFence)0);
1121 m_commandBuffers = std::vector<vk::VkCommandBuffer>(m_fences.size(), (vk::VkCommandBuffer)0);
1123 m_freeAcquireSemaphore = (vk::VkSemaphore)0;
1124 m_freeRenderSemaphore = (vk::VkSemaphore)0;
1126 m_freeAcquireSemaphore = createSemaphore(m_vkd, *m_device).disown();
1127 m_freeRenderSemaphore = createSemaphore(m_vkd, *m_device).disown();
1129 initImageViews(m_vkd, *m_device, m_swapchainImages, imageFormat, m_swapchainImageViews);
1130 initFramebuffers(m_vkd, *m_device, *m_renderPass, m_swapchainImageViews, imageWidth, imageHeight, m_framebuffers);
1131 initSemaphores(m_vkd, *m_device, m_acquireSemaphores);
1132 initSemaphores(m_vkd, *m_device, m_renderSemaphores);
1134 initFences(m_vkd, *m_device, m_fences);
1137 void IncrementalPresentTestInstance::deinitSwapchainResources (void)
1139 VK_CHECK(m_vkd.queueWaitIdle(m_queue));
1141 if (m_freeAcquireSemaphore != (vk::VkSemaphore)0)
1143 m_vkd.destroySemaphore(*m_device, m_freeAcquireSemaphore, DE_NULL);
1144 m_freeAcquireSemaphore = (vk::VkSemaphore)0;
1147 if (m_freeRenderSemaphore != (vk::VkSemaphore)0)
1149 m_vkd.destroySemaphore(*m_device, m_freeRenderSemaphore, DE_NULL);
1150 m_freeRenderSemaphore = (vk::VkSemaphore)0;
1153 deinitSemaphores(m_vkd, *m_device, m_acquireSemaphores);
1154 deinitSemaphores(m_vkd, *m_device, m_renderSemaphores);
1155 deinitFences(m_vkd, *m_device, m_fences);
1156 deinitCommandBuffers(m_vkd, *m_device, *m_commandPool, m_commandBuffers);
1157 deinitFramebuffers(m_vkd, *m_device, m_framebuffers);
1158 deinitImageViews(m_vkd, *m_device, m_swapchainImageViews);
1160 m_swapchainImages.clear();
1161 m_imageNextFrames.clear();
1164 m_swapchain = vk::Move<vk::VkSwapchainKHR>();
1165 m_renderPass = vk::Move<vk::VkRenderPass>();
1166 m_pipeline = vk::Move<vk::VkPipeline>();
1170 void IncrementalPresentTestInstance::render (void)
1172 const deUint64 foreverNs = 0xFFFFFFFFFFFFFFFFul;
1173 const vk::VkFence fence = m_fences[m_frameNdx % m_fences.size()];
1174 const deUint32 width = m_swapchainConfigs[m_swapchainConfigNdx].imageExtent.width;
1175 const deUint32 height = m_swapchainConfigs[m_swapchainConfigNdx].imageExtent.height;
1176 size_t imageNextFrame;
1178 // Throttle execution
1179 if (m_frameNdx >= m_fences.size())
1181 VK_CHECK(m_vkd.waitForFences(*m_device, 1u, &fence, VK_TRUE, foreverNs));
1182 VK_CHECK(m_vkd.resetFences(*m_device, 1u, &fence));
1184 m_vkd.freeCommandBuffers(*m_device, *m_commandPool, 1u, &m_commandBuffers[m_frameNdx % m_commandBuffers.size()]);
1185 m_commandBuffers[m_frameNdx % m_commandBuffers.size()] = (vk::VkCommandBuffer)0;
1188 vk::VkSemaphore currentAcquireSemaphore = m_freeAcquireSemaphore;
1189 vk::VkSemaphore currentRenderSemaphore = m_freeRenderSemaphore;
1190 deUint32 imageIndex;
1192 // Acquire next image
1193 VK_CHECK(m_vkd.acquireNextImageKHR(*m_device, *m_swapchain, foreverNs, currentAcquireSemaphore, fence, &imageIndex));
1195 // Create command buffer
1197 imageNextFrame = m_imageNextFrames[imageIndex];
1198 m_commandBuffers[m_frameNdx % m_commandBuffers.size()] = createCommandBuffer(m_vkd, *m_device, *m_commandPool, *m_pipelineLayout, *m_renderPass, m_framebuffers[imageIndex], *m_pipeline, m_swapchainImages[imageIndex], m_isFirst[imageIndex], imageNextFrame, m_frameNdx, width, height).disown();
1199 m_imageNextFrames[imageIndex] = m_frameNdx + 1;
1200 m_isFirst[imageIndex] = false;
1203 // Submit command buffer
1205 const vk::VkPipelineStageFlags dstStageMask = vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1206 const vk::VkSubmitInfo submitInfo =
1208 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1211 ¤tAcquireSemaphore,
1214 &m_commandBuffers[m_frameNdx % m_commandBuffers.size()],
1216 ¤tRenderSemaphore
1219 VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submitInfo, (vk::VkFence)0));
1223 if (m_useIncrementalPresent)
1225 vk::VkResult result;
1226 const vector<vk::VkRectLayerKHR> rects = getUpdatedRects(imageNextFrame, m_frameNdx, width, height);
1227 const vk::VkPresentRegionKHR region =
1229 (deUint32)rects.size(),
1230 rects.empty() ? DE_NULL : &rects[0]
1232 const vk::VkPresentRegionsKHR regionInfo =
1234 vk::VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR,
1239 const vk::VkPresentInfoKHR presentInfo =
1241 vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
1244 ¤tRenderSemaphore,
1251 VK_CHECK(m_vkd.queuePresentKHR(m_queue, &presentInfo));
1256 vk::VkResult result;
1257 const vk::VkPresentInfoKHR presentInfo =
1259 vk::VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
1262 ¤tRenderSemaphore,
1269 VK_CHECK(m_vkd.queuePresentKHR(m_queue, &presentInfo));
1274 m_freeAcquireSemaphore = m_acquireSemaphores[imageIndex];
1275 m_acquireSemaphores[imageIndex] = currentAcquireSemaphore;
1277 m_freeRenderSemaphore = m_renderSemaphores[imageIndex];
1278 m_renderSemaphores[imageIndex] = currentRenderSemaphore;
1282 tcu::TestStatus IncrementalPresentTestInstance::iterate (void)
1284 // Initialize swapchain specific resources
1288 if (m_frameNdx == 0)
1290 if (m_outOfDateCount == 0)
1291 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Swapchain: " << m_swapchainConfigs[m_swapchainConfigNdx] << tcu::TestLog::EndMessage;
1293 initSwapchainResources();
1298 catch (const vk::Error& error)
1300 if (error.getError() == vk::VK_ERROR_OUT_OF_DATE_KHR)
1302 m_swapchainConfigs = generateSwapchainConfigs(*m_surface, m_queueFamilyIndex, m_testConfig.scaling, m_surfaceProperties, m_surfaceFormats, m_presentModes, m_testConfig.presentMode);
1304 if (m_outOfDateCount < m_maxOutOfDateCount)
1306 m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx << ": Swapchain out of date. Recreating resources." << TestLog::EndMessage;
1307 deinitSwapchainResources();
1311 return tcu::TestStatus::incomplete();
1315 m_context.getTestContext().getLog() << TestLog::Message << "Frame " << m_frameNdx << ": Swapchain out of date." << TestLog::EndMessage;
1316 m_resultCollector.fail("Received too many VK_ERROR_OUT_OF_DATE_KHR errors. Received " + de::toString(m_outOfDateCount) + ", max " + de::toString(m_maxOutOfDateCount));
1321 m_resultCollector.fail(error.what());
1324 deinitSwapchainResources();
1326 m_swapchainConfigNdx++;
1328 m_outOfDateCount = 0;
1330 if (m_swapchainConfigNdx >= m_swapchainConfigs.size())
1331 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1333 return tcu::TestStatus::incomplete();
1338 if (m_frameNdx >= m_frameCount)
1341 m_outOfDateCount = 0;
1342 m_swapchainConfigNdx++;
1344 deinitSwapchainResources();
1346 if (m_swapchainConfigNdx >= m_swapchainConfigs.size())
1347 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1349 return tcu::TestStatus::incomplete();
1352 return tcu::TestStatus::incomplete();
1357 static void init (vk::SourceCollections& dst, TestConfig)
1359 dst.glslSources.add("quad-vert") << glu::VertexSource(
1361 "out gl_PerVertex {\n"
1362 "\tvec4 gl_Position;\n"
1365 "void main (void) {\n"
1366 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1367 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1369 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1371 "layout(location = 0) out highp vec4 o_color;\n"
1372 "layout(push_constant) uniform PushConstant {\n"
1373 "\thighp uint mask;\n"
1374 "} pushConstants;\n"
1375 "void main (void)\n"
1377 "\thighp uint mask = pushConstants.mask;\n"
1378 "\thighp uint x = mask ^ uint(gl_FragCoord.x);\n"
1379 "\thighp uint y = mask ^ uint(gl_FragCoord.y);\n"
1380 "\thighp uint r = 128u * bitfieldExtract(x, 0, 1)\n"
1381 "\t + 64u * bitfieldExtract(y, 1, 1)\n"
1382 "\t + 32u * bitfieldExtract(x, 3, 1);\n"
1383 "\thighp uint g = 128u * bitfieldExtract(y, 0, 1)\n"
1384 "\t + 64u * bitfieldExtract(x, 2, 1)\n"
1385 "\t + 32u * bitfieldExtract(y, 3, 1);\n"
1386 "\thighp uint b = 128u * bitfieldExtract(x, 1, 1)\n"
1387 "\t + 64u * bitfieldExtract(y, 2, 1)\n"
1388 "\t + 32u * bitfieldExtract(x, 4, 1);\n"
1389 "\to_color = vec4(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0, 1.0);\n"
1396 void createIncrementalPresentTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
1404 { SCALING_NONE, "scale_none" },
1405 { SCALING_UP, "scale_up" },
1406 { SCALING_DOWN, "scale_down" }
1410 vk::VkPresentModeKHR mode;
1414 { vk::VK_PRESENT_MODE_IMMEDIATE_KHR, "immediate" },
1415 { vk::VK_PRESENT_MODE_MAILBOX_KHR, "mailbox" },
1416 { vk::VK_PRESENT_MODE_FIFO_KHR, "fifo" },
1417 { vk::VK_PRESENT_MODE_FIFO_RELAXED_KHR, "fifo_relaxed" }
1420 for (size_t scalingNdx = 0; scalingNdx < DE_LENGTH_OF_ARRAY(scaling); scalingNdx++)
1422 if (scaling[scalingNdx].scaling != SCALING_NONE && wsiType == vk::wsi::TYPE_WAYLAND)
1425 if (scaling[scalingNdx].scaling != SCALING_NONE && vk::wsi::getPlatformProperties(wsiType).swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
1430 de::MovePtr<tcu::TestCaseGroup> scaleGroup (new tcu::TestCaseGroup(testGroup->getTestContext(), scaling[scalingNdx].name, scaling[scalingNdx].name));
1432 for (size_t presentModeNdx = 0; presentModeNdx < DE_LENGTH_OF_ARRAY(presentModes); presentModeNdx++)
1434 de::MovePtr<tcu::TestCaseGroup> presentModeGroup (new tcu::TestCaseGroup(testGroup->getTestContext(), presentModes[presentModeNdx].name, presentModes[presentModeNdx].name));
1436 for (size_t ref = 0; ref < 2; ref++)
1438 const bool isReference = (ref == 0);
1439 const char* const name = isReference ? "reference" : "incremental_present";
1442 config.wsiType = wsiType;
1443 config.scaling = scaling[scalingNdx].scaling;
1444 config.useIncrementalPresent = !isReference;
1445 config.presentMode = presentModes[presentModeNdx].mode;
1447 presentModeGroup->addChild(new vkt::InstanceFactory1<IncrementalPresentTestInstance, TestConfig, Programs>(testGroup->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, name, Programs(), config));
1450 scaleGroup->addChild(presentModeGroup.release());
1453 testGroup->addChild(scaleGroup.release());