| /*------------------------------------------------------------------------- |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2015 The Khronos Group Inc. |
| * Copyright (c) 2015 Samsung Electronics Co., Ltd. |
| * Copyright (c) 2015 Google 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. |
| * |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vkDefs.hpp" |
| #include "vktTestCaseUtil.hpp" |
| #include "vkBuilderUtil.hpp" |
| #include "vkPlatform.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "vkMemUtil.hpp" |
| #include "vkDeviceUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkAllocationCallbackUtil.hpp" |
| #include "vktApiCommandBuffersTests.hpp" |
| #include "vktApiBufferComputeInstance.hpp" |
| #include "vktApiComputeInstanceResultBuffer.hpp" |
| #include "deSharedPtr.hpp" |
| #include <sstream> |
| |
| namespace vkt |
| { |
| namespace api |
| { |
| namespace |
| { |
| |
| using namespace vk; |
| |
| typedef de::SharedPtr<vk::Unique<vk::VkEvent> > VkEventSp; |
| |
| // Global variables |
| const deUint64 INFINITE_TIMEOUT = ~(deUint64)0u; |
| |
| // Testcases |
| /********* 19.1. Command Pools (6.1 in VK 1.0 Spec) ***************************/ |
| tcu::TestStatus createPoolNullParamsTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| tcu::TestStatus createPoolNonNullAllocatorTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const VkAllocationCallbacks* allocationCallbacks = getSystemAllocator(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| createCommandPool(vk, vkDevice, &cmdPoolParams, allocationCallbacks); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| tcu::TestStatus createPoolTransientBitTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| tcu::TestStatus createPoolResetBitTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| tcu::TestStatus resetPoolReleaseResourcesBitTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL)); |
| |
| VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT)); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| tcu::TestStatus resetPoolNoFlagsTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams, DE_NULL)); |
| |
| VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, 0u)); |
| |
| return tcu::TestStatus::pass("Command Pool allocated correctly."); |
| } |
| |
| /******** 19.2. Command Buffer Lifetime (6.2 in VK 1.0 Spec) ******************/ |
| tcu::TestStatus allocatePrimaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // bufferCount; |
| }; |
| const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| return tcu::TestStatus::pass("Buffer was created correctly."); |
| } |
| |
| tcu::TestStatus allocateManyPrimaryBuffersTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities. |
| #if (DE_PTR_SIZE == 4) |
| const unsigned minCommandBuffer = 1024; |
| #else |
| const unsigned minCommandBuffer = 10000; |
| #endif |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| minCommandBuffer, // uint32_t bufferCount; |
| }; |
| |
| // do not keep the handles to buffers, as they will be freed with command pool |
| |
| // allocate the minimum required amount of buffers |
| VkCommandBuffer cmdBuffers[minCommandBuffer]; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers)); |
| |
| std::ostringstream out; |
| out << "allocateManyPrimaryBuffersTest succeded: created " << minCommandBuffer << " command buffers"; |
| |
| return tcu::TestStatus::pass(out.str()); |
| } |
| |
| tcu::TestStatus allocateZeroPrimaryBuffersTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 0u, // bufferCount; |
| }; |
| |
| VkCommandBuffer cmdBuffer; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffer)); |
| |
| return tcu::TestStatus::pass("allocateZeroPrimaryBuffersTest passed."); |
| } |
| |
| tcu::TestStatus allocateSecondaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 1u, // bufferCount; |
| }; |
| const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| return tcu::TestStatus::pass("Buffer was created correctly."); |
| } |
| |
| tcu::TestStatus allocateManySecondaryBuffersTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // \todo Determining the minimum number of command buffers should be a function of available system memory and driver capabilities. |
| #if (DE_PTR_SIZE == 4) |
| const unsigned minCommandBuffer = 1024; |
| #else |
| const unsigned minCommandBuffer = 10000; |
| #endif |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| minCommandBuffer, // uint32_t bufferCount; |
| }; |
| |
| // do not keep the handles to buffers, as they will be freed with command pool |
| |
| // allocate the minimum required amount of buffers |
| VkCommandBuffer cmdBuffers[minCommandBuffer]; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers)); |
| |
| std::ostringstream out; |
| out << "allocateManySecondaryBuffersTest succeded: created " << minCommandBuffer << " command buffers"; |
| |
| return tcu::TestStatus::pass(out.str()); |
| } |
| |
| tcu::TestStatus allocateZeroSecondaryBuffersTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 0u, // bufferCount; |
| }; |
| |
| VkCommandBuffer cmdBuffer; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffer)); |
| |
| return tcu::TestStatus::pass("allocateZeroSecondaryBuffersTest passed."); |
| } |
| |
| tcu::TestStatus executePrimaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the command buffer to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event); |
| if (result == VK_EVENT_SET) |
| return tcu::TestStatus::pass("Execute Primary Command Buffer succeeded"); |
| |
| return tcu::TestStatus::fail("Execute Primary Command Buffer FAILED"); |
| } |
| |
| tcu::TestStatus executeLargePrimaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const deUint32 LARGE_BUFFER_SIZE = 10000; |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx) |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL)))); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // set all the events |
| for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx) |
| { |
| vk.cmdSetEvent(*primCmdBuf, events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the command buffer to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if the buffer was executed correctly - all events had their status |
| // changed |
| tcu::TestStatus testResult = tcu::TestStatus::incomplete(); |
| |
| for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx) |
| { |
| if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET) |
| { |
| testResult = tcu::TestStatus::fail("An event was not set."); |
| break; |
| } |
| } |
| |
| if (!testResult.isComplete()) |
| testResult = tcu::TestStatus::pass("All events set correctly."); |
| |
| return testResult; |
| } |
| |
| tcu::TestStatus resetBufferImplicitlyTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // bufferCount; |
| }; |
| const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| const VkCommandBufferBeginInfo cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| }; |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // Put the command buffer in recording state. |
| VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo)); |
| { |
| // Set the event |
| vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(*cmdBuf)); |
| |
| // We'll use a fence to wait for the execution of the queue |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags |
| }; |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &cmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submitting the command buffer that sets the event to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get())); |
| |
| // Waiting for the queue to finish executing |
| VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| // Reset the fence so that we can reuse it |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| |
| // Check if the buffer was executed |
| if (vk.getEventStatus(vkDevice, *event) != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Failed to set the event."); |
| |
| // Reset the event |
| vk.resetEvent(vkDevice, *event); |
| if(vk.getEventStatus(vkDevice, *event) != VK_EVENT_RESET) |
| return tcu::TestStatus::fail("Failed to reset the event."); |
| |
| // Reset the command buffer by putting it in recording state again. This |
| // should empty the command buffer. |
| VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo)); |
| VK_CHECK(vk.endCommandBuffer(*cmdBuf)); |
| |
| // Submit the command buffer after resetting. It should have no commands |
| // recorded, so the event should remain unsignaled. |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get())); |
| // Waiting for the queue to finish executing |
| VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // Check if the event remained unset. |
| if(vk.getEventStatus(vkDevice, *event) == VK_EVENT_RESET) |
| return tcu::TestStatus::pass("Buffer was reset correctly."); |
| else |
| return tcu::TestStatus::fail("Buffer was not reset correctly."); |
| } |
| |
| /******** 19.3. Command Buffer Recording (6.3 in VK 1.0 Spec) *****************/ |
| tcu::TestStatus recordSinglePrimaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| return tcu::TestStatus::pass("Primary buffer recorded successfully."); |
| } |
| |
| tcu::TestStatus recordLargePrimaryBufferTest(Context &context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // define minimal amount of commands to accept |
| const long long unsigned minNumCommands = 10000llu; |
| |
| for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands ) |
| { |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| |
| // record resetting event |
| vk.cmdResetEvent(*primCmdBuf, *event,stageMask); |
| }; |
| |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the command buffer to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| return tcu::TestStatus::pass("hugeTest succeeded"); |
| } |
| |
| tcu::TestStatus recordSingleSecondaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, // renderPass |
| 0u, // subpass |
| (VkFramebuffer)0u, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| return tcu::TestStatus::pass("Secondary buffer recorded successfully."); |
| } |
| |
| tcu::TestStatus recordLargeSecondaryBufferTest(Context &context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // define minimal amount of commands to accept |
| const long long unsigned minNumCommands = 10000llu; |
| |
| for ( long long unsigned currentCommands = 0; currentCommands < minNumCommands / 2; ++currentCommands ) |
| { |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| |
| // record resetting event |
| vk.cmdResetEvent(*primCmdBuf, *event,stageMask); |
| }; |
| |
| |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the command buffer to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| return tcu::TestStatus::pass("hugeTest succeeded"); |
| } |
| |
| tcu::TestStatus submitPrimaryBufferTwiceTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffer |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| // check if buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Twice Test FAILED"); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if buffer has been executed |
| result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Twice Test FAILED"); |
| else |
| return tcu::TestStatus::pass("Submit Twice Test succeeded"); |
| } |
| |
| tcu::TestStatus submitSecondaryBufferTwiceTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| |
| const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| // Secondary Command buffer |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, // renderPass |
| 0u, // subpass |
| (VkFramebuffer)0u, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0u, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record first primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo)); |
| { |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event,stageMask); |
| } |
| |
| // end recording of secondary buffers |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get()); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf1)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo1 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf1.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| |
| // check if secondary buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED"); |
| |
| // reset first primary buffer |
| vk.resetCommandBuffer( *primCmdBuf1, 0u); |
| |
| // reset event to allow receiving it again |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record second primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo)); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get()); |
| } |
| // end recording |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf2)); |
| |
| // submit second primary buffer, the secondary should be executed too |
| const VkSubmitInfo submitInfo2 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf2.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if secondary buffer has been executed |
| result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED"); |
| else |
| return tcu::TestStatus::pass("Submit Twice Secondary Command Buffer succeeded"); |
| } |
| |
| tcu::TestStatus oneTimeSubmitFlagPrimaryBufferTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffer |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| |
| // check if buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED"); |
| |
| // record primary command buffer again - implicit reset because of VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event,stageMask); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if buffer has been executed |
| result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("oneTimeSubmitFlagPrimaryBufferTest FAILED"); |
| else |
| return tcu::TestStatus::pass("oneTimeSubmitFlagPrimaryBufferTest succeeded"); |
| } |
| |
| tcu::TestStatus oneTimeSubmitFlagSecondaryBufferTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| |
| const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| // Secondary Command buffer |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, // renderPass |
| 0u, // subpass |
| (VkFramebuffer)0u, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record first primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo)); |
| { |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event,stageMask); |
| } |
| |
| // end recording of secondary buffers |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get()); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf1)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo1 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf1.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo1, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| |
| // check if secondary buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Twice Secondary Command Buffer FAILED"); |
| |
| // reset first primary buffer |
| vk.resetCommandBuffer( *primCmdBuf1, 0u); |
| |
| // reset event to allow receiving it again |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record secondary command buffer again |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event,stageMask); |
| } |
| // end recording of secondary buffers |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| // record second primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo)); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get()); |
| } |
| // end recording |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf2)); |
| |
| // submit second primary buffer, the secondary should be executed too |
| const VkSubmitInfo submitInfo2 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf2.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fence)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if secondary buffer has been executed |
| result = vk.getEventStatus(vkDevice,*event); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("oneTimeSubmitFlagSecondaryBufferTest FAILED"); |
| else |
| return tcu::TestStatus::pass("oneTimeSubmitFlagSecondaryBufferTest succeeded"); |
| } |
| |
| tcu::TestStatus simultaneousUsePrimaryBufferTest(Context& context) |
| { |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> eventOne (createEvent(vk, vkDevice, &eventCreateInfo)); |
| const Unique<VkEvent> eventTwo (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *eventOne)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // wait for event |
| vk.cmdWaitEvents(*primCmdBuf, 1u, &eventOne.get(), stageMask, stageMask, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); |
| |
| // Set the second event |
| vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), stageMask); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence1 (createFence(vk, vkDevice, &fenceCreateInfo)); |
| const Unique<VkFence> fence2 (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit first buffer |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence1)); |
| |
| // submit second buffer |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence2)); |
| |
| // wait for both buffer to stop at event for 100 microseconds |
| vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, 100000); |
| vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, 100000); |
| |
| // set event |
| VK_CHECK(vk.setEvent(vkDevice, *eventOne)); |
| |
| // wait for end of execution of the first buffer |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence1.get(), 0u, INFINITE_TIMEOUT)); |
| // wait for end of execution of the second buffer |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence2.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // TODO: this will be true if the command buffer was executed only once |
| // TODO: add some test that will say if it was executed twice |
| |
| // check if buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice, *eventTwo); |
| if (result == VK_EVENT_SET) |
| return tcu::TestStatus::pass("simultaneous use - primary buffers test succeeded"); |
| else |
| return tcu::TestStatus::fail("simultaneous use - primary buffers test FAILED"); |
| } |
| |
| tcu::TestStatus simultaneousUseSecondaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| // Secondary Command buffer params |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, // renderPass |
| 0u, // subpass |
| (VkFramebuffer)0u, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> eventOne (createEvent(vk, vkDevice, &eventCreateInfo)); |
| const Unique<VkEvent> eventTwo (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *eventOne)); |
| VK_CHECK(vk.resetEvent(vkDevice, *eventTwo)); |
| |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // wait for event |
| vk.cmdWaitEvents(*secCmdBuf, 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); |
| |
| // reset event |
| vk.cmdSetEvent(*secCmdBuf, *eventTwo, stageMask); |
| } |
| // end recording of secondary buffers |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get()); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffer, the secondary should be executed too |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); |
| |
| // wait for both buffers to stop at event for 100 microseconds |
| vk.waitForFences(vkDevice, 1, &fence.get(), 0u, 100000); |
| |
| // set event |
| VK_CHECK(vk.setEvent(vkDevice, *eventOne)); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // TODO: this will be true if the command buffer was executed only once |
| // TODO: add some test that will say if it was executed twice |
| |
| // check if secondary buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*eventTwo); |
| if (result == VK_EVENT_SET) |
| return tcu::TestStatus::pass("Simulatous Secondary Command Buffer Execution succeeded"); |
| else |
| return tcu::TestStatus::fail("Simulatous Secondary Command Buffer Execution FAILED"); |
| } |
| |
| tcu::TestStatus recordBufferQueryPreciseWithFlagTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo primCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams)); |
| |
| // Secondary Command buffer params |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secBufferInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| 0u, // renderPass |
| 0u, // subpass |
| 0u, // framebuffer |
| VK_TRUE, // occlusionQueryEnable |
| VK_QUERY_CONTROL_PRECISE_BIT, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| &secBufferInheritInfo, |
| }; |
| |
| // Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set |
| const VkQueryPoolCreateInfo queryPoolCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| VK_QUERY_CONTROL_PRECISE_BIT, // flags |
| VK_QUERY_TYPE_OCCLUSION, // queryType |
| 1u, // entryCount |
| 0u, // pipelineStatistics |
| }; |
| Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo)); |
| |
| VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo)); |
| VK_CHECK(vk.endCommandBuffer(secCmdBuf.get())); |
| |
| VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo)); |
| { |
| vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u); |
| vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT); |
| { |
| vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get()); |
| } |
| vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u); |
| } |
| VK_CHECK(vk.endCommandBuffer(primCmdBuf.get())); |
| |
| return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query."); |
| } |
| |
| tcu::TestStatus recordBufferQueryImpreciseWithFlagTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo primCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams)); |
| |
| // Secondary Command buffer params |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secBufferInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| 0u, // renderPass |
| 0u, // subpass |
| 0u, // framebuffer |
| VK_TRUE, // occlusionQueryEnable |
| VK_QUERY_CONTROL_PRECISE_BIT, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| &secBufferInheritInfo, |
| }; |
| |
| // Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set |
| const VkQueryPoolCreateInfo queryPoolCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| VK_QUERY_TYPE_OCCLUSION, // queryType |
| 1u, // entryCount |
| 0u, // pipelineStatistics |
| }; |
| Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo)); |
| |
| VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo)); |
| VK_CHECK(vk.endCommandBuffer(secCmdBuf.get())); |
| |
| VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo)); |
| { |
| vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u); |
| vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT); |
| { |
| vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get()); |
| } |
| vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u); |
| } |
| VK_CHECK(vk.endCommandBuffer(primCmdBuf.get())); |
| |
| return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query."); |
| } |
| |
| tcu::TestStatus recordBufferQueryImpreciseWithoutFlagTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo primCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &primCmdBufParams)); |
| |
| // Secondary Command buffer params |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 1u, // flags; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secBufferInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| 0u, // renderPass |
| 0u, // subpass |
| 0u, // framebuffer |
| VK_TRUE, // occlusionQueryEnable |
| 0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| &secBufferInheritInfo, |
| }; |
| |
| // Create an occlusion query with VK_QUERY_CONTROL_PRECISE_BIT set |
| const VkQueryPoolCreateInfo queryPoolCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| (VkQueryPoolCreateFlags)0, |
| VK_QUERY_TYPE_OCCLUSION, |
| 1u, |
| 0u, |
| }; |
| Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo)); |
| |
| VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo)); |
| VK_CHECK(vk.endCommandBuffer(secCmdBuf.get())); |
| |
| VK_CHECK(vk.beginCommandBuffer(primCmdBuf.get(), &primBufferBeginInfo)); |
| { |
| vk.cmdResetQueryPool(primCmdBuf.get(), queryPool.get(), 0u, 1u); |
| vk.cmdBeginQuery(primCmdBuf.get(), queryPool.get(), 0u, VK_QUERY_CONTROL_PRECISE_BIT); |
| { |
| vk.cmdExecuteCommands(primCmdBuf.get(), 1u, &secCmdBuf.get()); |
| } |
| vk.cmdEndQuery(primCmdBuf.get(), queryPool.get(), 0u); |
| } |
| VK_CHECK(vk.endCommandBuffer(primCmdBuf.get())); |
| |
| return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query."); |
| } |
| |
| /******** 19.4. Command Buffer Submission (6.4 in VK 1.0 Spec) ****************/ |
| tcu::TestStatus submitBufferCountNonZero(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const deUint32 BUFFER_COUNT = 5u; |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| BUFFER_COUNT, // bufferCount; |
| }; |
| VkCommandBuffer cmdBuffers[BUFFER_COUNT]; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers)); |
| |
| const VkCommandBufferBeginInfo cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL)))); |
| } |
| |
| // Record the command buffers |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo)); |
| { |
| vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx])); |
| } |
| |
| // We'll use a fence to wait for the execution of the queue |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags |
| }; |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| BUFFER_COUNT, // commandBufferCount |
| cmdBuffers, // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the alpha command buffer to the queue |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get())); |
| // Wait for the queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT)); |
| |
| // Check if the buffers were executed |
| tcu::TestStatus testResult = tcu::TestStatus::incomplete(); |
| |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| if (vk.getEventStatus(vkDevice, events[ndx]->get()) != VK_EVENT_SET) |
| { |
| testResult = tcu::TestStatus::fail("Failed to set the event."); |
| break; |
| } |
| } |
| |
| if (!testResult.isComplete()) |
| testResult = tcu::TestStatus::pass("All buffers were submitted and executed correctly."); |
| |
| return testResult; |
| } |
| |
| tcu::TestStatus submitBufferCountEqualZero(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const deUint32 BUFFER_COUNT = 2u; |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| BUFFER_COUNT, // bufferCount; |
| }; |
| VkCommandBuffer cmdBuffers[BUFFER_COUNT]; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, cmdBuffers)); |
| |
| const VkCommandBufferBeginInfo cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL)))); |
| |
| // Record the command buffers |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo)); |
| { |
| vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx])); |
| } |
| |
| // We'll use a fence to wait for the execution of the queue |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags |
| }; |
| const Unique<VkFence> fenceZero (createFence(vk, vkDevice, &fenceCreateInfo)); |
| const Unique<VkFence> fenceOne (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfoCountZero = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &cmdBuffers[0], // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| const VkSubmitInfo submitInfoCountOne = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &cmdBuffers[1], // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Submit the command buffers to the queue |
| // We're performing two submits to make sure that the first one has |
| // a chance to be processed before we check the event's status |
| VK_CHECK(vk.queueSubmit(queue, 0, &submitInfoCountZero, fenceZero.get())); |
| VK_CHECK(vk.queueSubmit(queue, 1, &submitInfoCountOne, fenceOne.get())); |
| |
| const VkFence fences[] = |
| { |
| fenceZero.get(), |
| fenceOne.get(), |
| }; |
| |
| // Wait for the queue |
| VK_CHECK(vk.waitForFences(vkDevice, (deUint32)DE_LENGTH_OF_ARRAY(fences), fences, VK_TRUE, INFINITE_TIMEOUT)); |
| |
| // Check if the first buffer was executed |
| tcu::TestStatus testResult = tcu::TestStatus::incomplete(); |
| |
| if (vk.getEventStatus(vkDevice, events[0]->get()) == VK_EVENT_SET) |
| testResult = tcu::TestStatus::fail("The first event was signaled."); |
| else |
| testResult = tcu::TestStatus::pass("The first submission was ignored."); |
| |
| return testResult; |
| } |
| |
| tcu::TestStatus submitBufferNullFence(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const short BUFFER_COUNT = 2; |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // bufferCount; |
| }; |
| VkCommandBuffer cmdBuffers[BUFFER_COUNT]; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, &cmdBuffers[ndx])); |
| |
| const VkCommandBufferBeginInfo cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags; |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice, &eventCreateInfo, DE_NULL)))); |
| |
| // Record the command buffers |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &cmdBufBeginInfo)); |
| { |
| vk.cmdSetEvent(cmdBuffers[ndx], events[ndx]->get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx])); |
| } |
| |
| // We'll use a fence to wait for the execution of the queue |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| 0u, // flags |
| }; |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfoNullFence = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &cmdBuffers[0], // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| const VkSubmitInfo submitInfoNonNullFence = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &cmdBuffers[1], // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // Perform two submissions - one with no fence, the other one with a valid |
| // fence Hoping submitting the other buffer will give the first one time to |
| // execute |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNullFence, DE_NULL)); |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoNonNullFence, fence.get())); |
| |
| // Wait for the queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), VK_TRUE, INFINITE_TIMEOUT)); |
| |
| tcu::TestStatus testResult = tcu::TestStatus::incomplete(); |
| |
| if (vk.getEventStatus(vkDevice, events[0]->get()) != VK_EVENT_SET) |
| testResult = tcu::TestStatus::fail("The first event was not signaled -> the buffer was not executed."); |
| else |
| testResult = tcu::TestStatus::pass("The first event was signaled -> the buffer with null fence submitted and executed correctly."); |
| |
| return testResult; |
| } |
| |
| /******** 19.5. Secondary Command Buffer Execution (6.6 in VK 1.0 Spec) *******/ |
| tcu::TestStatus executeSecondaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags; |
| queueFamilyIndex, // queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level; |
| 1u, // bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBuf (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| // Secondary Command buffer |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType; |
| DE_NULL, // pNext; |
| *cmdPool, // commandPool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level; |
| 1u, // bufferCount; |
| }; |
| const Unique<VkCommandBuffer> secCmdBuf (allocateCommandBuffer(vk, vkDevice, &secCmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| DE_NULL, // renderPass |
| 0u, // subpass |
| DE_NULL, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event, stageMask); |
| } |
| // end recording of the secondary buffer |
| VK_CHECK(vk.endCommandBuffer(*secCmdBuf)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf, &primCmdBufBeginInfo)); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf, 1u, &secCmdBuf.get()); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBuf)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice, &fenceCreateInfo)); |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1u, // commandBufferCount |
| &primCmdBuf.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffer, the secondary should be executed too |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get())); |
| |
| // wait for end of execution of queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // check if secondary buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice, *event); |
| if (result == VK_EVENT_SET) |
| return tcu::TestStatus::pass("executeSecondaryBufferTest succeeded"); |
| |
| return tcu::TestStatus::fail("executeSecondaryBufferTest FAILED"); |
| } |
| |
| tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context) |
| { |
| const deUint32 BUFFER_COUNT = 10u; |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| const VkCommandPoolCreateInfo cmdPoolParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); |
| |
| // Command buffer |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| 1u, // uint32_t bufferCount; |
| }; |
| const Unique<VkCommandBuffer> primCmdBufOne (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const Unique<VkCommandBuffer> primCmdBufTwo (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| // Secondary Command buffers params |
| const VkCommandBufferAllocateInfo secCmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *cmdPool, // VkCommandPool pool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| BUFFER_COUNT, // uint32_t bufferCount; |
| }; |
| VkCommandBuffer cmdBuffers[BUFFER_COUNT]; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &secCmdBufParams, cmdBuffers)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| 0, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, // renderPass |
| 0u, // subpass |
| (VkFramebuffer)0u, // framebuffer |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, // queryFlags |
| (VkQueryPipelineStatisticFlags)0u, // pipelineStatistics |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| // Fill create info struct for event |
| const VkEventCreateInfo eventCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, |
| DE_NULL, |
| 0u, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> eventOne (createEvent(vk, vkDevice, &eventCreateInfo)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *eventOne)); |
| |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // wait for event |
| vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), stageMask, stageMask, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); |
| } |
| // end recording of secondary buffers |
| VK_CHECK(vk.endCommandBuffer(cmdBuffers[ndx])); |
| }; |
| |
| // record primary command buffer one |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo)); |
| { |
| // execute one secondary buffer |
| vk.cmdExecuteCommands(*primCmdBufOne, 1, cmdBuffers ); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBufOne)); |
| |
| // record primary command buffer two |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo)); |
| { |
| // execute one secondary buffer with all buffers |
| vk.cmdExecuteCommands(*primCmdBufTwo, BUFFER_COUNT, cmdBuffers ); |
| } |
| VK_CHECK(vk.endCommandBuffer(*primCmdBufTwo)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fenceOne (createFence(vk, vkDevice, &fenceCreateInfo)); |
| const Unique<VkFence> fenceTwo (createFence(vk, vkDevice, &fenceCreateInfo)); |
| |
| const VkSubmitInfo submitInfoOne = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBufOne.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffer, the secondary should be executed too |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne)); |
| |
| // wait for buffer to stop at event for 100 microseconds |
| vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000); |
| |
| const VkSubmitInfo submitInfoTwo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBufTwo.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit second primary buffer, the secondary should be executed too |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo)); |
| |
| // wait for all buffers to stop at event for 100 microseconds |
| vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000); |
| |
| // now all buffers are waiting at eventOne |
| // set event eventOne |
| VK_CHECK(vk.setEvent(vkDevice, *eventOne)); |
| |
| // wait for end of execution of fenceOne |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT)); |
| |
| // wait for end of execution of second queue |
| VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT)); |
| |
| return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded"); |
| } |
| |
| /******** 19.6. Commands Allowed Inside Command Buffers (6.7 in VK 1.0 Spec) **/ |
| tcu::TestStatus orderBindPipelineTest(Context& context) |
| { |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| Allocator& allocator = context.getDefaultAllocator(); |
| const ComputeInstanceResultBuffer result (vk, device, allocator); |
| |
| enum |
| { |
| ADDRESSABLE_SIZE = 256, // allocate a lot more than required |
| }; |
| |
| const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); |
| const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f); |
| const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f); |
| const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f); |
| |
| const deUint32 dataOffsetA = (0u); |
| const deUint32 dataOffsetB = (0u); |
| const deUint32 viewOffsetA = (0u); |
| const deUint32 viewOffsetB = (0u); |
| const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE; |
| const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE; |
| |
| de::MovePtr<Allocation> bufferMemA; |
| const Unique<VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context)); |
| |
| de::MovePtr<Allocation> bufferMemB; |
| const Unique<VkBuffer> bufferB (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB, context)); |
| |
| const Unique<VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout(context)); |
| const Unique<VkDescriptorPool> descriptorPool (createDescriptorPool(context)); |
| const Unique<VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, result.getBuffer(), context)); |
| const VkDescriptorSet descriptorSets[] = { *descriptorSet }; |
| const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets); |
| |
| const VkPipelineLayoutCreateInfo layoutCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| (VkPipelineLayoutCreateFlags)0, |
| numDescriptorSets, // setLayoutCount |
| &descriptorSetLayout.get(), // pSetLayouts |
| 0u, // pushConstantRangeCount |
| DE_NULL, // pPushConstantRanges |
| }; |
| Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device, &layoutCreateInfo)); |
| |
| const Unique<VkShaderModule> computeModuleGood (createShaderModule(vk, device, context.getBinaryCollection().get("compute_good"), (VkShaderModuleCreateFlags)0u)); |
| const Unique<VkShaderModule> computeModuleBad (createShaderModule(vk, device, context.getBinaryCollection().get("compute_bad"), (VkShaderModuleCreateFlags)0u)); |
| |
| const VkPipelineShaderStageCreateInfo shaderCreateInfoGood = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
| DE_NULL, |
| (VkPipelineShaderStageCreateFlags)0, |
| VK_SHADER_STAGE_COMPUTE_BIT, // stage |
| *computeModuleGood, // shader |
| "main", |
| DE_NULL, // pSpecializationInfo |
| }; |
| |
| const VkPipelineShaderStageCreateInfo shaderCreateInfoBad = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
| DE_NULL, |
| (vk::VkPipelineShaderStageCreateFlags)0, |
| vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage |
| *computeModuleBad, // shader |
| "main", |
| DE_NULL, // pSpecializationInfo |
| }; |
| |
| const VkComputePipelineCreateInfo createInfoGood = |
| { |
| VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| shaderCreateInfoGood, // cs |
| *pipelineLayout, // layout |
| (vk::VkPipeline)0, // basePipelineHandle |
| 0u, // basePipelineIndex |
| }; |
| |
| const VkComputePipelineCreateInfo createInfoBad = |
| { |
| VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| shaderCreateInfoBad, // cs |
| *pipelineLayout, // descriptorSetLayout.get() |
| (VkPipeline)0, // basePipelineHandle |
| 0u, // basePipelineIndex |
| }; |
| |
| const Unique<VkPipeline> pipelineGood (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoGood)); |
| const Unique<VkPipeline> pipelineBad (createComputePipeline(vk, device, (VkPipelineCache)0u, &createInfoBad)); |
| |
| const VkAccessFlags inputBit = (VK_ACCESS_UNIFORM_READ_BIT); |
| const VkBufferMemoryBarrier bufferBarriers[] = |
| { |
| { |
| VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, |
| DE_NULL, |
| VK_ACCESS_HOST_WRITE_BIT, // outputMask |
| inputBit, // inputMask |
| VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex |
| VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex |
| *bufferA, // buffer |
| (VkDeviceSize)0u, // offset |
| (VkDeviceSize)bufferSizeA, // size |
| }, |
| { |
| VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, |
| DE_NULL, |
| VK_ACCESS_HOST_WRITE_BIT, // outputMask |
| inputBit, // inputMask |
| VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex |
| VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex |
| *bufferB, // buffer |
| (VkDeviceSize)0u, // offset |
| (VkDeviceSize)bufferSizeB, // size |
| } |
| }; |
| |
| const deUint32 numSrcBuffers = 1u; |
| |
| const deUint32* const dynamicOffsets = (DE_NULL); |
| const deUint32 numDynamicOffsets = (0); |
| const int numPreBarriers = numSrcBuffers; |
| const vk::VkBufferMemoryBarrier* const postBarriers = result.getResultReadBarrier(); |
| const int numPostBarriers = 1; |
| const tcu::Vec4 refQuadrantValue14 = (colorA2); |
| const tcu::Vec4 refQuadrantValue23 = (colorA1); |
| const tcu::Vec4 references[4] = |
| { |
| refQuadrantValue14, |
| refQuadrantValue23, |
| refQuadrantValue23, |
| refQuadrantValue14, |
| }; |
| tcu::Vec4 results[4]; |
| |
| // submit and wait begin |
| |
| const tcu::UVec3 numWorkGroups = tcu::UVec3(4, 1u, 1); |
| |
| const VkCommandPoolCreateInfo cmdPoolCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType; |
| DE_NULL, // pNext |
| VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags |
| queueFamilyIndex, // queueFamilyIndex |
| }; |
| const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo)); |
| |
| const VkFenceCreateInfo fenceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| }; |
| |
| const VkCommandBufferAllocateInfo cmdBufCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType |
| DE_NULL, // pNext |
| *cmdPool, // commandPool |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level |
| 1u, // bufferCount; |
| }; |
| |
| const VkCommandBufferBeginInfo cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| (const VkCommandBufferInheritanceInfo*)DE_NULL, |
| }; |
| |
| const Unique<VkFence> cmdCompleteFence (createFence(vk, device, &fenceCreateInfo)); |
| const Unique<VkCommandBuffer> cmd (allocateCommandBuffer(vk, device, &cmdBufCreateInfo)); |
| |
| VK_CHECK(vk.beginCommandBuffer(*cmd, &cmdBufBeginInfo)); |
| |
| vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineBad); |
| vk.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineGood); |
| vk.cmdBindDescriptorSets(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, numDynamicOffsets, dynamicOffsets); |
| |
| if (numPreBarriers) |
| vk.cmdPipelineBarrier(*cmd, 0u, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, |
| 0, (const VkMemoryBarrier*)DE_NULL, |
| numPreBarriers, bufferBarriers, |
| 0, (const VkImageMemoryBarrier*)DE_NULL); |
| |
| vk.cmdDispatch(*cmd, numWorkGroups.x(), numWorkGroups.y(), numWorkGroups.z()); |
| vk.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, |
| 0, (const VkMemoryBarrier*)DE_NULL, |
| numPostBarriers, postBarriers, |
| 0, (const VkImageMemoryBarrier*)DE_NULL); |
| VK_CHECK(vk.endCommandBuffer(*cmd)); |
| |
| // run |
| // submit second primary buffer, the secondary should be executed too |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &cmd.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *cmdCompleteFence)); |
| |
| VK_CHECK(vk.waitForFences(device, 1u, &cmdCompleteFence.get(), 0u, INFINITE_TIMEOUT)); // \note: timeout is failure |
| VK_CHECK(vk.resetFences(device, 1u, &cmdCompleteFence.get())); |
| |
| // submit and wait end |
| result.readResultContentsTo(&results); |
| |
| // verify |
| if (results[0] == references[0] && |
| results[1] == references[1] && |
| results[2] == references[2] && |
| results[3] == references[3]) |
| { |
| return tcu::TestStatus::pass("Pass"); |
| } |
| else if (results[0] == tcu::Vec4(-1.0f) && |
| results[1] == tcu::Vec4(-1.0f) && |
| results[2] == tcu::Vec4(-1.0f) && |
| results[3] == tcu::Vec4(-1.0f)) |
| { |
| context.getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "Result buffer was not written to." |
| << tcu::TestLog::EndMessage; |
| return tcu::TestStatus::fail("Result buffer was not written to"); |
| } |
| else |
| { |
| context.getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "Error expected [" |
| << references[0] << ", " |
| << references[1] << ", " |
| << references[2] << ", " |
| << references[3] << "], got [" |
| << results[0] << ", " |
| << results[1] << ", " |
| << results[2] << ", " |
| << results[3] << "]" |
| << tcu::TestLog::EndMessage; |
| return tcu::TestStatus::fail("Invalid result values"); |
| } |
| } |
| |
| // Shaders |
| void genComputeSource (SourceCollections& programCollection) |
| { |
| const char* const versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES); |
| std::ostringstream buf_good; |
| |
| buf_good << versionDecl << "\n" |
| << "" |
| << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1) in;\n" |
| << "layout(set = 0, binding = 1u, std140) uniform BufferName\n" |
| << "{\n" |
| << " highp vec4 colorA;\n" |
| << " highp vec4 colorB;\n" |
| << "} b_instance;\n" |
| << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n" |
| << "{\n" |
| << " highp vec4 read_colors[4];\n" |
| << "} b_out;\n" |
| << "void main(void)\n" |
| << "{\n" |
| << " highp int quadrant_id = int(gl_WorkGroupID.x);\n" |
| << " highp vec4 result_color;\n" |
| << " if (quadrant_id == 1 || quadrant_id == 2)\n" |
| << " result_color = b_instance.colorA;\n" |
| << " else\n" |
| << " result_color = b_instance.colorB;\n" |
| << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n" |
| << "}\n"; |
| |
| programCollection.glslSources.add("compute_good") << glu::ComputeSource(buf_good.str()); |
| |
| std::ostringstream buf_bad; |
| |
| buf_bad << versionDecl << "\n" |
| << "" |
| << "layout(local_size_x = 1u, local_size_y = 1u, local_size_z = 1) in;\n" |
| << "layout(set = 0, binding = 1u, std140) uniform BufferName\n" |
| << "{\n" |
| << " highp vec4 colorA;\n" |
| << " highp vec4 colorB;\n" |
| << "} b_instance;\n" |
| << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n" |
| << "{\n" |
| << " highp vec4 read_colors[4];\n" |
| << "} b_out;\n" |
| << "void main(void)\n" |
| << "{\n" |
| << " highp int quadrant_id = int(gl_WorkGroupID.x);\n" |
| << " highp vec4 result_color;\n" |
| << " if (quadrant_id == 1 || quadrant_id == 2)\n" |
| << " result_color = b_instance.colorA;\n" |
| << " else\n" |
| << " result_color = b_instance.colorB;\n" |
| << " b_out.read_colors[gl_WorkGroupID.x] = vec4(0.0, 0.0, 0.0, 0.0);\n" |
| << "}\n"; |
| |
| programCollection.glslSources.add("compute_bad") << glu::ComputeSource(buf_bad.str()); |
| } |
| |
| } // anonymous |
| |
| tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx) |
| { |
| de::MovePtr<tcu::TestCaseGroup> commandBuffersTests (new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests")); |
| |
| /* 19.1. Command Pools (6.1 in VK 1.0 Spec) */ |
| addFunctionCase (commandBuffersTests.get(), "pool_create_null_params", "", createPoolNullParamsTest); |
| addFunctionCase (commandBuffersTests.get(), "pool_create_non_null_allocator", "", createPoolNonNullAllocatorTest); |
| addFunctionCase (commandBuffersTests.get(), "pool_create_transient_bit", "", createPoolTransientBitTest); |
| addFunctionCase (commandBuffersTests.get(), "pool_create_reset_bit", "", createPoolResetBitTest); |
| addFunctionCase (commandBuffersTests.get(), "pool_reset_release_res", "", resetPoolReleaseResourcesBitTest); |
| addFunctionCase (commandBuffersTests.get(), "pool_reset_no_flags_res", "", resetPoolNoFlagsTest); |
| /* 19.2. Command Buffer Lifetime (6.2 in VK 1.0 Spec) */ |
| addFunctionCase (commandBuffersTests.get(), "allocate_single_primary", "", allocatePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "allocate_many_primary", "", allocateManyPrimaryBuffersTest); |
| addFunctionCase (commandBuffersTests.get(), "allocate_zero_primary", "", allocateZeroPrimaryBuffersTest); |
| addFunctionCase (commandBuffersTests.get(), "allocate_single_secondary", "", allocateSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "allocate_many_secondary", "", allocateManySecondaryBuffersTest); |
| addFunctionCase (commandBuffersTests.get(), "allocate_zero_secondary", "", allocateZeroSecondaryBuffersTest); |
| addFunctionCase (commandBuffersTests.get(), "execute_small_primary", "", executePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "execute_large_primary", "", executeLargePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "reset_implicit", "", resetBufferImplicitlyTest); |
| /* 19.3. Command Buffer Recording (6.3 in VK 1.0 Spec) */ |
| addFunctionCase (commandBuffersTests.get(), "record_single_primary", "", recordSinglePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_many_primary", "", recordLargePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_single_secondary", "", recordSingleSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_many_secondary", "", recordLargeSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "submit_twice_primary", "", submitPrimaryBufferTwiceTest); |
| addFunctionCase (commandBuffersTests.get(), "submit_twice_secondary", "", submitSecondaryBufferTwiceTest); |
| addFunctionCase (commandBuffersTests.get(), "record_one_time_submit_primary", "", oneTimeSubmitFlagPrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_one_time_submit_secondary", "", oneTimeSubmitFlagSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_simul_use_primary", "", simultaneousUsePrimaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_simul_use_secondary", "", simultaneousUseSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "record_query_precise_w_flag", "", recordBufferQueryPreciseWithFlagTest); |
| addFunctionCase (commandBuffersTests.get(), "record_query_imprecise_w_flag", "", recordBufferQueryImpreciseWithFlagTest); |
| addFunctionCase (commandBuffersTests.get(), "record_query_imprecise_wo_flag", "", recordBufferQueryImpreciseWithoutFlagTest); |
| /* 19.4. Command Buffer Submission (6.4 in VK 1.0 Spec) */ |
| addFunctionCase (commandBuffersTests.get(), "submit_count_non_zero", "", submitBufferCountNonZero); |
| addFunctionCase (commandBuffersTests.get(), "submit_count_equal_zero", "", submitBufferCountEqualZero); |
| addFunctionCase (commandBuffersTests.get(), "submit_null_fence", "", submitBufferNullFence); |
| /* 19.5. Secondary Command Buffer Execution (6.6 in VK 1.0 Spec) */ |
| addFunctionCase (commandBuffersTests.get(), "secondary_execute", "", executeSecondaryBufferTest); |
| addFunctionCase (commandBuffersTests.get(), "secondary_execute_twice", "", executeSecondaryBufferTwiceTest); |
| /* 19.6. Commands Allowed Inside Command Buffers (6.7 in VK 1.0 Spec) */ |
| addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_bind_pipeline", "", genComputeSource, orderBindPipelineTest); |
| |
| return commandBuffersTests.release(); |
| } |
| |
| } // api |
| } // vkt |
| |