| /*------------------------------------------------------------------------ |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Synchronization fence basic tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktSynchronizationBasicFenceTests.hpp" |
| #include "vktTestCaseUtil.hpp" |
| #include "vktSynchronizationUtil.hpp" |
| |
| #include "vkDefs.hpp" |
| #include "vkPlatform.hpp" |
| #include "vkRef.hpp" |
| #include "vkCmdUtil.hpp" |
| |
| namespace vkt |
| { |
| namespace synchronization |
| { |
| namespace |
| { |
| using namespace vk; |
| |
| static const deUint64 SHORT_FENCE_WAIT = 1000ull; |
| static const deUint64 LONG_FENCE_WAIT = ~0ull; |
| |
| tcu::TestStatus basicOneFenceCase (Context& context) |
| { |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); |
| const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); |
| |
| const VkFenceCreateInfo fenceInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkFenceCreateFlags flags; |
| }; |
| |
| const Unique<VkFence> fence (createFence(vk, device, &fenceInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // deUint32 waitSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pWaitSemaphores; |
| (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; |
| 1u, // deUint32 commandBufferCount; |
| &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; |
| 0u, // deUint32 signalSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pSignalSemaphores; |
| }; |
| |
| if (VK_NOT_READY != vk.getFenceStatus(device, *fence)) |
| return tcu::TestStatus::fail("Created fence should be in unsignaled state"); |
| |
| if (VK_TIMEOUT != vk.waitForFences(device, 1u, &fence.get(), VK_TRUE, SHORT_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_TIMEOUT"); |
| |
| if (VK_NOT_READY != vk.getFenceStatus(device, *fence)) |
| return tcu::TestStatus::fail("Created fence should be in unsignaled state"); |
| |
| beginCommandBuffer(vk, *cmdBuffer); |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| if (VK_SUCCESS != vk.getFenceStatus(device, *fence)) |
| return tcu::TestStatus::fail("Fence should be in signaled state"); |
| |
| if (VK_SUCCESS != vk.resetFences(device, 1u, &fence.get())) |
| return tcu::TestStatus::fail("Couldn't reset the fence"); |
| |
| if (VK_NOT_READY != vk.getFenceStatus(device, *fence)) |
| return tcu::TestStatus::fail("Fence after reset should be in unsignaled state"); |
| |
| return tcu::TestStatus::pass("Basic one fence tests passed"); |
| } |
| |
| tcu::TestStatus basicMultiFenceCase (Context& context) |
| { |
| enum |
| { |
| FIRST_FENCE = 0, |
| SECOND_FENCE |
| }; |
| |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); |
| const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); |
| |
| const VkFenceCreateInfo fenceInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkFenceCreateFlags flags; |
| }; |
| |
| const Move<VkFence> ptrFence[2] = |
| { |
| createFence(vk, device, &fenceInfo), |
| createFence(vk, device, &fenceInfo) |
| }; |
| |
| const VkFence fence[2] = |
| { |
| *ptrFence[FIRST_FENCE], |
| *ptrFence[SECOND_FENCE] |
| }; |
| |
| const VkCommandBufferBeginInfo info = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags; |
| DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; |
| }; |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // deUint32 waitSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pWaitSemaphores; |
| (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; |
| 1u, // deUint32 commandBufferCount; |
| &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; |
| 0u, // deUint32 signalSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pSignalSemaphores; |
| }; |
| |
| VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info)); |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE])); |
| |
| if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence[FIRST_FENCE], DE_FALSE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| if (VK_SUCCESS != vk.resetFences(device, 1u, &fence[FIRST_FENCE])) |
| return tcu::TestStatus::fail("Couldn't reset the fence"); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE])); |
| |
| if (VK_TIMEOUT != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, SHORT_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_TIMEOUT"); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[SECOND_FENCE])); |
| |
| if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| return tcu::TestStatus::pass("Basic multi fence tests passed"); |
| } |
| |
| tcu::TestStatus emptySubmitCase (Context& context) |
| { |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| const VkQueue queue = context.getUniversalQueue(); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkFenceCreateFlags)0, // VkFenceCreateFlags flags; |
| }; |
| |
| const Unique<VkFence> fence (createFence(vk, device, &fenceCreateInfo)); |
| |
| VK_CHECK(vk.queueSubmit(queue, 0u, DE_NULL, *fence)); |
| |
| if (VK_SUCCESS != vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| return tcu::TestStatus::pass("OK"); |
| } |
| |
| tcu::TestStatus basicMultiFenceWaitAllFalseCase (Context& context) |
| { |
| enum |
| { |
| FIRST_FENCE = 0, |
| SECOND_FENCE |
| }; |
| |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); |
| const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); |
| |
| const VkFenceCreateInfo fenceInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkFenceCreateFlags flags; |
| }; |
| |
| const Move<VkFence> ptrFence[2] = |
| { |
| createFence(vk, device, &fenceInfo), |
| createFence(vk, device, &fenceInfo) |
| }; |
| |
| const VkFence fence[2] = |
| { |
| *ptrFence[FIRST_FENCE], |
| *ptrFence[SECOND_FENCE] |
| }; |
| |
| const VkCommandBufferBeginInfo info = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // VkCommandBufferUsageFlags flags; |
| DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; |
| }; |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // deUint32 waitSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pWaitSemaphores; |
| (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; |
| 1u, // deUint32 commandBufferCount; |
| &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; |
| 0u, // deUint32 signalSemaphoreCount; |
| DE_NULL, // const VkSemaphore* pSignalSemaphores; |
| }; |
| |
| VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &info)); |
| endCommandBuffer(vk, *cmdBuffer); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[FIRST_FENCE])); |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence[SECOND_FENCE])); |
| |
| // Wait for any fence |
| if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_FALSE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| // Wait for all fences |
| if (VK_SUCCESS != vk.waitForFences(device, 2u, &fence[FIRST_FENCE], DE_TRUE, LONG_FENCE_WAIT)) |
| return tcu::TestStatus::fail("vkWaitForFences should return VK_SUCCESS"); |
| |
| return tcu::TestStatus::pass("Basic multi fence test without waitAll passed"); |
| } |
| |
| } // anonymous |
| |
| tcu::TestCaseGroup* createBasicFenceTests (tcu::TestContext& testCtx) |
| { |
| de::MovePtr<tcu::TestCaseGroup> basicFenceTests(new tcu::TestCaseGroup(testCtx, "fence", "Basic fence tests")); |
| addFunctionCase(basicFenceTests.get(), "one", "Basic one fence tests", basicOneFenceCase); |
| addFunctionCase(basicFenceTests.get(), "multi", "Basic multi fence tests", basicMultiFenceCase); |
| addFunctionCase(basicFenceTests.get(), "empty_submit", "Signal a fence after an empty queue submission", emptySubmitCase); |
| addFunctionCase(basicFenceTests.get(), "multi_waitall_false", "Basic multi fence test without waitAll", basicMultiFenceWaitAllFalseCase); |
| |
| return basicFenceTests.release(); |
| } |
| |
| } // synchronization |
| } // vkt |