xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiFrameBoundaryTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Advanced Micro Devices, Inc.
6  * Copyright (c) 2019 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21 * \file
22 * \brief VK_EXT_frame_boundary tests
23 *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiFrameBoundaryTests.hpp"
26 #include "vktTestGroupUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 
29 #include "vkCmdUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkStrUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkWsiUtil.hpp"
35 
36 #include "tcuTestLog.hpp"
37 #include "tcuPlatform.hpp"
38 
39 #include <iostream>
40 #include <string>
41 #include <vector>
42 
43 #include <string.h>
44 
45 namespace vkt
46 {
47 namespace api
48 {
49 namespace
50 {
51 
52 using namespace vk;
53 
54 enum ExtensionUse
55 {
56     EXTENSION_USE_NONE,
57     EXTENSION_USE_SYNC2,
58 };
59 
60 enum TestType
61 {
62     TEST_TYPE_SINGLE_FRAME,
63     TEST_TYPE_SINGLE_FRAME_MULTIPLE_SUBMISSIONS,
64     TEST_TYPE_MULTIPLE_FRAMES,
65     TEST_TYPE_MULTIPLE_FRAMES_MULTIPLE_SUBMISSIONS,
66     TEST_TYPE_MULTIPLE_OVERLAPPING_SUBMISSIONS,
67 
68     TEST_TYPE_LAST,
69 };
70 
71 struct TestParams
72 {
73     ExtensionUse m_extensionUse;
74     TestType m_testType;
75 };
76 
checkSupport(Context & context,TestParams params)77 void checkSupport(Context &context, TestParams params)
78 {
79     context.requireDeviceFunctionality("VK_EXT_frame_boundary");
80 
81     if (params.m_extensionUse == EXTENSION_USE_SYNC2)
82         context.requireDeviceFunctionality("VK_KHR_synchronization2");
83 }
84 
checkWsiSupport(Context & context,vk::wsi::Type wsiType)85 void checkWsiSupport(Context &context, vk::wsi::Type wsiType)
86 {
87     context.requireDeviceFunctionality("VK_EXT_frame_boundary");
88 
89     context.requireInstanceFunctionality("VK_KHR_surface");
90     context.requireInstanceFunctionality(vk::wsi::getExtensionName(wsiType));
91     context.requireDeviceFunctionality("VK_KHR_swapchain");
92 }
93 
recordCommands(Context & context,VkCommandBuffer cmdBuffer,VkImage image)94 void recordCommands(Context &context, VkCommandBuffer cmdBuffer, VkImage image)
95 {
96     const DeviceInterface &vk = context.getDeviceInterface();
97 
98     beginCommandBuffer(vk, cmdBuffer);
99 
100     const VkImageMemoryBarrier imageBarrier = {
101         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType            sType
102         DE_NULL,                                // const void*                pNext
103         0,                                      // VkAccessFlags            srcAccessMask
104         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags            dstAccessMask
105         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout            oldLayout
106         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout            newLayout
107         VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    srcQueueFamilyIndex
108         VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    destQueueFamilyIndex
109         image,                                  // VkImage                    image
110         {
111             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags        aspectMask
112             0u,                        // uint32_t                    baseMipLevel
113             VK_REMAINING_MIP_LEVELS,   // uint32_t                    levelCount
114             0u,                        // uint32_t                    baseArrayLayer
115             VK_REMAINING_ARRAY_LAYERS, // uint32_t                    layerCount
116         },                             // VkImageSubresourceRange    subresourceRange
117     };
118 
119     vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, DE_NULL,
120                           0, DE_NULL, 1, &imageBarrier);
121 
122     const VkClearColorValue clearColor{{1.0f, 1.0f, 1.0f, 1.0f}};
123     const VkImageSubresourceRange range{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
124 
125     vk.cmdClearColorImage(cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
126     endCommandBuffer(vk, cmdBuffer);
127 }
128 
submitCommands(ExtensionUse extensionUse,Context & context,VkCommandBuffer cmdBuffer,bool lastInFrame,uint32_t frameID,VkImage * pImages)129 void submitCommands(ExtensionUse extensionUse, Context &context, VkCommandBuffer cmdBuffer, bool lastInFrame,
130                     uint32_t frameID, VkImage *pImages)
131 {
132     const DeviceInterface &vk = context.getDeviceInterface();
133     const VkDevice vkDevice   = context.getDevice();
134 
135     const VkFenceCreateInfo fenceParams = {
136         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType        sType
137         DE_NULL,                             // const void*            pNext
138         0u,                                  // VkFenceCreateFlags    flags
139     };
140 
141     const Move<VkFence> fence = createFence(vk, vkDevice, &fenceParams);
142 
143     VkFrameBoundaryEXT frameBoundary = {
144         VK_STRUCTURE_TYPE_FRAME_BOUNDARY_EXT, // VkStructureType            sType
145         DE_NULL,                              // const void*                pNext
146         0u,                                   // VkFrameBoundaryFlagsEXT    flags
147         frameID,                              // uint64_t                    frameID
148         (lastInFrame ? 1u : 0u),              // uint32_t                    imageCount
149         (lastInFrame ? pImages : DE_NULL),    // const VkImage*            pImages
150         0u,                                   // uint32_t bufferCount;
151         DE_NULL,                              // VkBuffer* pBuffers;
152         0u,                                   // uint64_t                    tagName
153         0u,                                   // size_t                    tagSize
154         DE_NULL,                              // const void*                pTag
155     };
156 
157     if (lastInFrame)
158         frameBoundary.flags = VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT;
159 
160     switch (extensionUse)
161     {
162     case EXTENSION_USE_NONE:
163     {
164         const VkSubmitInfo submitInfo = {
165             VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType                sType
166             &frameBoundary,                // const void*                    pNext
167             0,                             // uint32_t                        waitSemaphoreCount
168             DE_NULL,                       // const VkSemaphore*            pWaitSemaphores
169             DE_NULL,                       // const VkPipelineStageFlags*    pWaitDstStageMask
170             1,                             // uint32_t                        commandBufferCount
171             &cmdBuffer,                    // const VkCommandBuffer*        pCommandBuffers
172             0u,                            // uint32_t                        signalSemaphoreCount
173             DE_NULL,                       // const VkSemaphore*            pSignalSemaphores
174         };
175 
176         VK_CHECK(vk.queueSubmit(context.getUniversalQueue(), 1, &submitInfo, *fence));
177         break;
178     }
179     case EXTENSION_USE_SYNC2:
180     {
181         const VkCommandBufferSubmitInfo cmdBufferSubmitInfo = {
182             VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR, // VkStructureType    sType
183             DE_NULL,                                          // const void*        pNext
184             cmdBuffer,                                        // VkCommandBuffer    commandBuffer
185             0u,                                               // uint32_t            deviceMask
186         };
187 
188         const VkSubmitInfo2 submitInfo2KHR = {
189             VK_STRUCTURE_TYPE_SUBMIT_INFO_2, // VkStructureType                    sType
190             &frameBoundary,                  // const void*                        pNext
191             0u,                              // VkSubmitFlagsKHR                    flags
192             0u,                              // uint32_t                            waitSemaphoreInfoCount
193             DE_NULL,                         // const VkSemaphoreSubmitInfo*        pWaitSemaphoreInfos
194             1u,                              // uint32_t                            commandBufferInfoCount
195             &cmdBufferSubmitInfo,            // const VkCommandBufferSubmitInfo*    pCommandBufferInfos
196             0u,                              // uint32_t                            signalSemaphoreInfoCount
197             DE_NULL,                         // const VkSemaphoreSubmitInfo*        pSignalSemaphoreInfos
198         };
199 
200         VK_CHECK(vk.queueSubmit2(context.getUniversalQueue(), 1, &submitInfo2KHR, *fence));
201         break;
202     }
203     default:
204         DE_ASSERT(false);
205     }
206 
207     VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~0ull));
208 }
209 
testCase(Context & context,TestParams params)210 tcu::TestStatus testCase(Context &context, TestParams params)
211 {
212     const DeviceInterface &vk = context.getDeviceInterface();
213     const VkDevice vkDevice   = context.getDevice();
214 
215     const VkExtent3D extent{16, 16, 1};
216     const VkImageCreateInfo imageParams = {
217         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType        sType
218         DE_NULL,                                                           // const void*            pNext
219         0u,                                                                // VkImageCreateFlags    flags
220         VK_IMAGE_TYPE_2D,                                                  // VkImageType            imageType
221         VK_FORMAT_R8G8B8A8_UNORM,                                          // VkFormat                format
222         extent,                                                            // VkExtent3D            extent
223         1u,                                                                // uint32_t                mipLevels
224         1u,                                                                // uint32_t                arraySize
225         VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t                samples
226         VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling        tiling
227         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags    usage
228         VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode        sharingMode
229         0u,                        // uint32_t                queueFamilyIndexCount
230         (const uint32_t *)DE_NULL, // const uint32_t*        pQueueFamilyIndices
231         VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout        initialLayout
232     };
233 
234     Move<VkImage> image                     = createImage(vk, vkDevice, &imageParams);
235     VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vk, vkDevice, *image);
236     de::MovePtr<Allocation> imageAllocation =
237         context.getDefaultAllocator().allocate(memoryRequirements, MemoryRequirement::Any);
238     VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageAllocation->getMemory(), 0u));
239 
240     Move<VkCommandPool> cmdPool     = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
241                                                         context.getUniversalQueueFamilyIndex());
242     Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
243     VkImage frameImages[]           = {*image};
244 
245     recordCommands(context, *cmdBuffer, *image);
246 
247     switch (params.m_testType)
248     {
249     case TEST_TYPE_SINGLE_FRAME:
250     {
251         submitCommands(params.m_extensionUse, context, *cmdBuffer, true, 1, frameImages);
252         break;
253     }
254     case TEST_TYPE_SINGLE_FRAME_MULTIPLE_SUBMISSIONS:
255     {
256         for (uint32_t i = 0; i < 4; i++)
257         {
258             bool lastInFrame = (i == 3);
259             submitCommands(params.m_extensionUse, context, *cmdBuffer, lastInFrame, 1, frameImages);
260         }
261 
262         break;
263     }
264     case TEST_TYPE_MULTIPLE_FRAMES:
265     {
266         for (uint32_t i = 1; i <= 4; i++)
267             submitCommands(params.m_extensionUse, context, *cmdBuffer, true, i, frameImages);
268 
269         break;
270     }
271     case TEST_TYPE_MULTIPLE_FRAMES_MULTIPLE_SUBMISSIONS:
272     {
273         for (uint32_t i = 1; i <= 4; i++)
274         {
275             submitCommands(params.m_extensionUse, context, *cmdBuffer, false, i, frameImages);
276             submitCommands(params.m_extensionUse, context, *cmdBuffer, true, i, frameImages);
277         }
278 
279         break;
280     }
281     case TEST_TYPE_MULTIPLE_OVERLAPPING_SUBMISSIONS:
282     {
283         submitCommands(params.m_extensionUse, context, *cmdBuffer, false, 1, frameImages);
284         submitCommands(params.m_extensionUse, context, *cmdBuffer, false, 2, frameImages);
285         submitCommands(params.m_extensionUse, context, *cmdBuffer, true, 1, frameImages);
286         submitCommands(params.m_extensionUse, context, *cmdBuffer, false, 3, frameImages);
287         submitCommands(params.m_extensionUse, context, *cmdBuffer, true, 2, frameImages);
288         submitCommands(params.m_extensionUse, context, *cmdBuffer, false, 4, frameImages);
289         submitCommands(params.m_extensionUse, context, *cmdBuffer, true, 3, frameImages);
290         submitCommands(params.m_extensionUse, context, *cmdBuffer, true, 4, frameImages);
291         break;
292     }
293     default:
294         DE_ASSERT(false);
295     }
296 
297     return tcu::TestStatus::pass("Pass");
298 }
299 
300 typedef std::vector<VkExtensionProperties> Extensions;
301 
createDisplay(const vk::Platform & platform,const Extensions & supportedExtensions,wsi::Type wsiType)302 de::MovePtr<wsi::Display> createDisplay(const vk::Platform &platform, const Extensions &supportedExtensions,
303                                         wsi::Type wsiType)
304 {
305     try
306     {
307         return de::MovePtr<wsi::Display>(platform.createWsiDisplay(wsiType));
308     }
309     catch (const tcu::NotSupportedError &e)
310     {
311         if (isExtensionStructSupported(supportedExtensions, RequiredExtension(wsi::getExtensionName(wsiType))) &&
312             platform.hasDisplay(wsiType))
313         {
314             // If VK_KHR_{platform}_surface was supported, vk::Platform implementation
315             // must support creating native display & window for that WSI type.
316             throw tcu::TestError(e.getMessage());
317         }
318         else
319             throw;
320     }
321 }
322 
createWindow(const wsi::Display & display,const tcu::Maybe<tcu::UVec2> & initialSize)323 de::MovePtr<wsi::Window> createWindow(const wsi::Display &display, const tcu::Maybe<tcu::UVec2> &initialSize)
324 {
325     try
326     {
327         return de::MovePtr<wsi::Window>(display.createWindow(initialSize));
328     }
329     catch (const tcu::NotSupportedError &e)
330     {
331         // See createDisplay - assuming that wsi::Display was supported platform port
332         // should also support creating a window.
333         throw tcu::TestError(e.getMessage());
334     }
335 }
336 
337 struct NativeObjects
338 {
339     const de::UniquePtr<wsi::Display> display;
340     const de::UniquePtr<wsi::Window> window;
341 
NativeObjectsvkt::api::__anon13ec37ef0111::NativeObjects342     NativeObjects(Context &context, const Extensions &supportedExtensions, wsi::Type wsiType,
343                   const tcu::Maybe<tcu::UVec2> &initialWindowSize = tcu::Nothing)
344         : display(
345               createDisplay(context.getTestContext().getPlatform().getVulkanPlatform(), supportedExtensions, wsiType))
346         , window(createWindow(*display, initialWindowSize))
347     {
348     }
349 };
350 
createSwapchain(Context & context,VkSurfaceKHR surface)351 Move<VkSwapchainKHR> createSwapchain(Context &context, VkSurfaceKHR surface)
352 {
353     const InstanceInterface &vki            = context.getInstanceInterface();
354     const DeviceInterface &vk               = context.getDeviceInterface();
355     const VkDevice vkDevice                 = context.getDevice();
356     const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
357 
358     const VkSurfaceCapabilitiesKHR capabilities =
359         wsi::getPhysicalDeviceSurfaceCapabilities(vki, vkPhysicalDevice, surface);
360 
361     if (!(capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT))
362         TCU_THROW(NotSupportedError, "supportedUsageFlags does not contain VK_IMAGE_USAGE_TRANSFER_DST_BIT");
363 
364     const std::vector<VkSurfaceFormatKHR> surfaceFormats =
365         wsi::getPhysicalDeviceSurfaceFormats(vki, vkPhysicalDevice, surface);
366 
367     const VkSurfaceFormatKHR surfaceFormat = surfaceFormats[0];
368 
369     const VkExtent2D swapchainExtent = {
370         de::clamp(16u, capabilities.minImageExtent.width, capabilities.maxImageExtent.width),
371         de::clamp(16u, capabilities.minImageExtent.height, capabilities.maxImageExtent.height)};
372 
373     const VkSwapchainCreateInfoKHR swapchainParams = {
374         VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, // VkStructureType                    sType
375         DE_NULL,                                     // const void*                        pNext
376         0u,                                          // VkSwapchainCreateFlagsKHR        flags
377         surface,                                     // VkSurfaceKHR                        surface
378         std::max(1u, capabilities.minImageCount),    // uint32_t                            minImageCount
379         surfaceFormat.format,                        // VkFormat                            imageFormat
380         surfaceFormat.colorSpace,                    // VkColorSpaceKHR                    imageColorSpace
381         swapchainExtent,                             // VkExtent2D                        imageExtent
382         1,                                           // uint32_t                            imageArrayLayers
383         VK_IMAGE_USAGE_TRANSFER_DST_BIT,             // VkImageUsageFlags                imageUsage
384         VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode                    imageSharingMode
385         0u,                                          // uint32_t                            queueFamilyIndexCount
386         (const uint32_t *)DE_NULL,                   // const uint32_t*                    pQueueFamilyIndices
387         capabilities.currentTransform,               // VkSurfaceTransformFlagBitsKHR    preTransform
388         VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,           // VkCompositeAlphaFlagBitsKHR        compositeAlpha
389         VK_PRESENT_MODE_FIFO_KHR,                    // VkPresentModeKHR                    presentMode
390         VK_FALSE,                                    // VkBool32                            clipped
391         (VkSwapchainKHR)0                            // VkSwapchainKHR                    oldSwapchain
392     };
393 
394     return createSwapchainKHR(vk, vkDevice, &swapchainParams);
395 }
396 
testCaseWsi(Context & context,vk::wsi::Type wsiType)397 tcu::TestStatus testCaseWsi(Context &context, vk::wsi::Type wsiType)
398 {
399     const InstanceInterface &vki = context.getInstanceInterface();
400     const DeviceInterface &vk    = context.getDeviceInterface();
401     const VkInstance vkInstance  = context.getInstance();
402     const VkDevice vkDevice      = context.getDevice();
403 
404     const NativeObjects native(context, enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL),
405                                wsiType);
406     const Unique<VkSurfaceKHR> surface(wsi::createSurface(vki, vkInstance, wsiType, *native.display, *native.window,
407                                                           context.getTestContext().getCommandLine()));
408     const Unique<VkSwapchainKHR> swapchain(createSwapchain(context, *surface));
409     const std::vector<VkImage> swapchainImages = wsi::getSwapchainImages(vk, vkDevice, *swapchain);
410 
411     const Move<VkCommandPool> cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
412                                                           context.getUniversalQueueFamilyIndex());
413     const Move<VkCommandBuffer> cmdBuffer =
414         allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
415 
416     const VkSemaphoreCreateInfo semaphoreCreateInfo = {
417         VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // VkStructureType sType;
418         DE_NULL,                                 // const void* pNext;
419         0u,                                      // VkSemaphoreCreateFlags flags;
420     };
421 
422     const Move<VkSemaphore> acquireSemaphore = createSemaphore(vk, vkDevice, &semaphoreCreateInfo);
423 
424     VkSemaphore acquireSemaphores[]      = {*acquireSemaphore};
425     VkPipelineStageFlags waitStageMask[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
426 
427     uint32_t currentBuffer = 0;
428     VK_CHECK(vk.acquireNextImageKHR(vkDevice, *swapchain, ~0ull, *acquireSemaphore, VK_NULL_HANDLE, &currentBuffer));
429 
430     recordCommands(context, *cmdBuffer, swapchainImages[currentBuffer]);
431 
432     submitCommandsAndWait(vk, vkDevice, context.getUniversalQueue(), *cmdBuffer, false, 0U, 1U, acquireSemaphores,
433                           waitStageMask);
434 
435     VkSwapchainKHR swapchains[] = {*swapchain};
436     VkImage frameImages[]       = {swapchainImages[currentBuffer]};
437 
438     const VkFrameBoundaryEXT frameBoundary = {
439         VK_STRUCTURE_TYPE_FRAME_BOUNDARY_EXT, // VkStructureType            sType
440         DE_NULL,                              // const void*                pNext
441         VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT,  // VkFrameBoundaryFlagsEXT    flags
442         1,                                    // uint64_t                    frameID
443         1u,                                   // uint32_t                    imageCount
444         frameImages,                          // const VkImage*            pImages
445         0u,                                   // uint32_t bufferCount;
446         DE_NULL,                              // VkBuffer* pBuffers;
447         0u,                                   // uint64_t                    tagName
448         0u,                                   // size_t                    tagSize
449         DE_NULL,                              // const void*                pTag
450     };
451 
452     const VkPresentInfoKHR presentInfo = {
453         VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // VkStructureType sType;
454         &frameBoundary,                     // const void* pNext;
455         0U,                                 // uint32_t waitSemaphoreCount;
456         DE_NULL,                            // const VkSemaphore* pWaitSemaphores;
457         1U,                                 // uint32_t swapchainCount;
458         swapchains,                         // const VkSwapchainKHR* pSwapchains;
459         &currentBuffer,                     // const uint32_t* pImageIndices;
460         DE_NULL,                            // VkResult* pResults;
461     };
462 
463     VK_CHECK(vk.queuePresentKHR(context.getUniversalQueue(), &presentInfo));
464 
465     return tcu::TestStatus::pass("Pass");
466 }
467 
createExecTestCases(tcu::TestCaseGroup * group,ExtensionUse extensionUse)468 void createExecTestCases(tcu::TestCaseGroup *group, ExtensionUse extensionUse)
469 {
470     const std::string testName[TEST_TYPE_LAST] = {
471         "single_frame",
472         "single_frame_multi_submissions",
473         "multi_frame",
474         "multi_frame_multi_submissions",
475         "multi_frame_overlapping_submissions",
476     };
477 
478     for (uint32_t testType = 0; testType < TEST_TYPE_LAST; testType++)
479     {
480         TestParams testParams{extensionUse, (TestType)testType};
481         addFunctionCase(group, testName[testType], checkSupport, testCase, testParams);
482     }
483 }
484 
createWsiTestCases(tcu::TestCaseGroup * group)485 void createWsiTestCases(tcu::TestCaseGroup *group)
486 {
487     for (uint32_t wsiType = 0; wsiType < wsi::TYPE_LAST; wsiType++)
488     {
489         addFunctionCase(group, wsi::getName((wsi::Type)wsiType), checkWsiSupport, testCaseWsi, (wsi::Type)wsiType);
490     }
491 }
492 
createTestCases(tcu::TestCaseGroup * group)493 void createTestCases(tcu::TestCaseGroup *group)
494 {
495     // VK_EXT_frame_boundary tests
496     addTestGroup(group, "core", createExecTestCases, EXTENSION_USE_NONE);
497     addTestGroup(group, "sync2", createExecTestCases, EXTENSION_USE_SYNC2);
498     addTestGroup(group, "wsi", createWsiTestCases);
499 }
500 
501 } // namespace
502 
createFrameBoundaryTests(tcu::TestContext & testCtx)503 tcu::TestCaseGroup *createFrameBoundaryTests(tcu::TestContext &testCtx)
504 {
505     // VK_EXT_frame_boundary tests
506     return createTestGroup(testCtx, "frame_boundary", createTestCases);
507 }
508 
509 } // namespace api
510 } // namespace vkt
511