| /*------------------------------------------------------------------------- |
| * 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 "vkCmdUtil.hpp" |
| #include "vkObjUtil.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vkPrograms.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkAllocationCallbackUtil.hpp" |
| #include "vkCmdUtil.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; |
| |
| |
| template <deUint32 NumBuffers> |
| class CommandBufferBareTestEnvironment |
| { |
| public: |
| CommandBufferBareTestEnvironment (Context& context, |
| VkCommandPoolCreateFlags commandPoolCreateFlags); |
| |
| VkCommandPool getCommandPool (void) const { return *m_commandPool; } |
| VkCommandBuffer getCommandBuffer (deUint32 bufferIndex) const; |
| |
| protected: |
| Context& m_context; |
| const VkDevice m_device; |
| const DeviceInterface& m_vkd; |
| const VkQueue m_queue; |
| const deUint32 m_queueFamilyIndex; |
| Allocator& m_allocator; |
| |
| // \note All VkCommandBuffers are allocated from m_commandPool so there is no need |
| // to free them separately as the auto-generated dtor will do that through |
| // destroying the pool. |
| Move<VkCommandPool> m_commandPool; |
| VkCommandBuffer m_primaryCommandBuffers[NumBuffers]; |
| }; |
| |
| template <deUint32 NumBuffers> |
| CommandBufferBareTestEnvironment<NumBuffers>::CommandBufferBareTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags) |
| : m_context (context) |
| , m_device (context.getDevice()) |
| , m_vkd (context.getDeviceInterface()) |
| , m_queue (context.getUniversalQueue()) |
| , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex()) |
| , m_allocator (context.getDefaultAllocator()) |
| { |
| m_commandPool = createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex); |
| |
| const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *m_commandPool, // VkCommandPool commandPool; |
| VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; |
| NumBuffers // deUint32 commandBufferCount; |
| }; |
| |
| VK_CHECK(m_vkd.allocateCommandBuffers(m_device, &cmdBufferAllocateInfo, m_primaryCommandBuffers)); |
| } |
| |
| template <deUint32 NumBuffers> |
| VkCommandBuffer CommandBufferBareTestEnvironment<NumBuffers>::getCommandBuffer(deUint32 bufferIndex) const |
| { |
| DE_ASSERT(bufferIndex < NumBuffers); |
| return m_primaryCommandBuffers[bufferIndex]; |
| } |
| |
| class CommandBufferRenderPassTestEnvironment : public CommandBufferBareTestEnvironment<1> |
| { |
| public: |
| CommandBufferRenderPassTestEnvironment (Context& context, |
| VkCommandPoolCreateFlags commandPoolCreateFlags); |
| |
| VkRenderPass getRenderPass (void) const { return *m_renderPass; } |
| VkFramebuffer getFrameBuffer (void) const { return *m_frameBuffer; } |
| VkCommandBuffer getPrimaryCommandBuffer (void) const { return getCommandBuffer(0); } |
| VkCommandBuffer getSecondaryCommandBuffer (void) const { return *m_secondaryCommandBuffer; } |
| |
| void beginPrimaryCommandBuffer (VkCommandBufferUsageFlags usageFlags); |
| void beginSecondaryCommandBuffer (VkCommandBufferUsageFlags usageFlags); |
| void beginRenderPass (VkSubpassContents content); |
| void submitPrimaryCommandBuffer (void); |
| de::MovePtr<tcu::TextureLevel> readColorAttachment (void); |
| |
| static const VkImageType DEFAULT_IMAGE_TYPE; |
| static const VkFormat DEFAULT_IMAGE_FORMAT; |
| static const VkExtent3D DEFAULT_IMAGE_SIZE; |
| static const VkRect2D DEFAULT_IMAGE_AREA; |
| |
| protected: |
| |
| Move<VkImage> m_colorImage; |
| Move<VkImageView> m_colorImageView; |
| Move<VkRenderPass> m_renderPass; |
| Move<VkFramebuffer> m_frameBuffer; |
| de::MovePtr<Allocation> m_colorImageMemory; |
| Move<VkCommandBuffer> m_secondaryCommandBuffer; |
| |
| }; |
| |
| const VkImageType CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_TYPE = VK_IMAGE_TYPE_2D; |
| const VkFormat CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_FORMAT = VK_FORMAT_R8G8B8A8_UINT; |
| const VkExtent3D CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE = {255, 255, 1}; |
| const VkRect2D CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA = |
| { |
| { 0u, 0u, }, // VkOffset2D offset; |
| { DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height }, // VkExtent2D extent; |
| }; |
| |
| CommandBufferRenderPassTestEnvironment::CommandBufferRenderPassTestEnvironment(Context& context, VkCommandPoolCreateFlags commandPoolCreateFlags) |
| : CommandBufferBareTestEnvironment<1> (context, commandPoolCreateFlags) |
| { |
| m_renderPass = makeRenderPass(m_vkd, m_device, DEFAULT_IMAGE_FORMAT); |
| |
| { |
| const VkImageCreateInfo imageCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageCreateFlags flags; |
| DEFAULT_IMAGE_TYPE, // VkImageType imageType; |
| DEFAULT_IMAGE_FORMAT, // VkFormat format; |
| DEFAULT_IMAGE_SIZE, // VkExtent3D extent; |
| 1, // deUint32 mipLevels; |
| 1, // deUint32 arrayLayers; |
| VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; |
| VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; |
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | |
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT | |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 1, // deUint32 queueFamilyIndexCount; |
| &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; |
| VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; |
| }; |
| |
| m_colorImage = createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL); |
| } |
| |
| m_colorImageMemory = m_allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, *m_colorImage), MemoryRequirement::Any); |
| VK_CHECK(m_vkd.bindImageMemory(m_device, *m_colorImage, m_colorImageMemory->getMemory(), m_colorImageMemory->getOffset())); |
| |
| { |
| const VkImageViewCreateInfo imageViewCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkImageViewCreateFlags flags; |
| *m_colorImage, // VkImage image; |
| VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; |
| DEFAULT_IMAGE_FORMAT, // VkFormat format; |
| { |
| VK_COMPONENT_SWIZZLE_R, |
| VK_COMPONENT_SWIZZLE_G, |
| VK_COMPONENT_SWIZZLE_B, |
| VK_COMPONENT_SWIZZLE_A |
| }, // VkComponentMapping components; |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; |
| 0u, // deUint32 baseMipLevel; |
| 1u, // deUint32 mipLevels; |
| 0u, // deUint32 baseArrayLayer; |
| 1u, // deUint32 arraySize; |
| }, // VkImageSubresourceRange subresourceRange; |
| }; |
| |
| m_colorImageView = createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL); |
| } |
| |
| { |
| const VkImageView attachmentViews[1] = |
| { |
| *m_colorImageView |
| }; |
| |
| const VkFramebufferCreateInfo framebufferCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkFramebufferCreateFlags flags; |
| *m_renderPass, // VkRenderPass renderPass; |
| 1, // deUint32 attachmentCount; |
| attachmentViews, // const VkImageView* pAttachments; |
| DEFAULT_IMAGE_SIZE.width, // deUint32 width; |
| DEFAULT_IMAGE_SIZE.height, // deUint32 height; |
| 1u, // deUint32 layers; |
| }; |
| |
| m_frameBuffer = createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL); |
| } |
| |
| { |
| const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *m_commandPool, // VkCommandPool commandPool; |
| VK_COMMAND_BUFFER_LEVEL_SECONDARY, // VkCommandBufferLevel level; |
| 1u // deUint32 commandBufferCount; |
| }; |
| |
| m_secondaryCommandBuffer = allocateCommandBuffer(m_vkd, m_device, &cmdBufferAllocateInfo); |
| |
| } |
| } |
| |
| void CommandBufferRenderPassTestEnvironment::beginRenderPass(VkSubpassContents content) |
| { |
| vk::beginRenderPass(m_vkd, m_primaryCommandBuffers[0], *m_renderPass, *m_frameBuffer, DEFAULT_IMAGE_AREA, tcu::UVec4(17, 59, 163, 251), content); |
| } |
| |
| void CommandBufferRenderPassTestEnvironment::beginPrimaryCommandBuffer(VkCommandBufferUsageFlags usageFlags) |
| { |
| beginCommandBuffer(m_vkd, m_primaryCommandBuffers[0], usageFlags); |
| } |
| |
| void CommandBufferRenderPassTestEnvironment::beginSecondaryCommandBuffer(VkCommandBufferUsageFlags usageFlags) |
| { |
| const VkCommandBufferInheritanceInfo commandBufferInheritanceInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| *m_renderPass, // VkRenderPass renderPass; |
| 0u, // deUint32 subpass; |
| *m_frameBuffer, // VkFramebuffer framebuffer; |
| VK_FALSE, // VkBool32 occlusionQueryEnable; |
| 0u, // VkQueryControlFlags queryFlags; |
| 0u // VkQueryPipelineStatisticFlags pipelineStatistics; |
| }; |
| |
| const VkCommandBufferBeginInfo commandBufferBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| usageFlags, // VkCommandBufferUsageFlags flags; |
| &commandBufferInheritanceInfo // const VkCommandBufferInheritanceInfo* pInheritanceInfo; |
| }; |
| |
| VK_CHECK(m_vkd.beginCommandBuffer(*m_secondaryCommandBuffer, &commandBufferBeginInfo)); |
| |
| } |
| |
| void CommandBufferRenderPassTestEnvironment::submitPrimaryCommandBuffer(void) |
| { |
| submitCommandsAndWait(m_vkd, m_device, m_queue, *m_primaryCommandBuffers); |
| } |
| |
| de::MovePtr<tcu::TextureLevel> CommandBufferRenderPassTestEnvironment::readColorAttachment () |
| { |
| Move<VkBuffer> buffer; |
| de::MovePtr<Allocation> bufferAlloc; |
| const tcu::TextureFormat tcuFormat = mapVkFormat(DEFAULT_IMAGE_FORMAT); |
| const VkDeviceSize pixelDataSize = DEFAULT_IMAGE_SIZE.height * DEFAULT_IMAGE_SIZE.height * tcuFormat.getPixelSize(); |
| de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height)); |
| |
| // Create destination buffer |
| { |
| const VkBufferCreateInfo bufferParams = |
| { |
| VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| 0u, // VkBufferCreateFlags flags; |
| pixelDataSize, // VkDeviceSize size; |
| VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; |
| VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; |
| 0u, // deUint32 queueFamilyIndexCount; |
| DE_NULL // const deUint32* pQueueFamilyIndices; |
| }; |
| |
| buffer = createBuffer(m_vkd, m_device, &bufferParams); |
| bufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, *buffer), MemoryRequirement::HostVisible); |
| VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); |
| } |
| |
| // Copy image to buffer |
| beginPrimaryCommandBuffer(0); |
| copyImageToBuffer(m_vkd, m_primaryCommandBuffers[0], *m_colorImage, *buffer, tcu::IVec2(DEFAULT_IMAGE_SIZE.width, DEFAULT_IMAGE_SIZE.height)); |
| endCommandBuffer(m_vkd, m_primaryCommandBuffers[0]); |
| |
| submitPrimaryCommandBuffer(); |
| |
| // Read buffer data |
| invalidateAlloc(m_vkd, m_device, *bufferAlloc); |
| tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr())); |
| |
| return resultLevel; |
| } |
| |
| |
| // Testcases |
| /********* 19.1. Command Pools (5.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(); |
| |
| createCommandPool(vk, vkDevice, 0u, queueFamilyIndex); |
| |
| 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."); |
| } |
| |
| bool executeCommandBuffer (const VkDevice device, |
| const DeviceInterface& vk, |
| const VkQueue queue, |
| const VkCommandBuffer commandBuffer, |
| const bool exitBeforeEndCommandBuffer = false) |
| { |
| const Unique<VkEvent> event (createEvent(vk, device)); |
| beginCommandBuffer(vk, commandBuffer, 0u); |
| { |
| const VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| vk.cmdSetEvent(commandBuffer, *event, stageMask); |
| if (exitBeforeEndCommandBuffer) |
| return exitBeforeEndCommandBuffer; |
| } |
| endCommandBuffer(vk, commandBuffer); |
| |
| submitCommandsAndWait(vk, device, queue, commandBuffer); |
| |
| // check if buffer has been executed |
| const VkResult result = vk.getEventStatus(device, *event); |
| return result == VK_EVENT_SET; |
| } |
| |
| tcu::TestStatus resetPoolReuseTest (Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| const VkQueue queue = context.getUniversalQueue(); |
| |
| 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)); |
| 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 Move<VkCommandBuffer> commandBuffers[] = |
| { |
| allocateCommandBuffer(vk, vkDevice, &cmdBufParams), |
| allocateCommandBuffer(vk, vkDevice, &cmdBufParams) |
| }; |
| |
| if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0]))) |
| return tcu::TestStatus::fail("Failed"); |
| if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1]), true)) |
| return tcu::TestStatus::fail("Failed"); |
| |
| VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT)); |
| |
| if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[0]))) |
| return tcu::TestStatus::fail("Failed"); |
| if (!executeCommandBuffer(vkDevice, vk, queue, *(commandBuffers[1]))) |
| return tcu::TestStatus::fail("Failed"); |
| |
| { |
| const Unique<VkCommandBuffer> afterResetCommandBuffers(allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| if (!executeCommandBuffer(vkDevice, vk, queue, *afterResetCommandBuffers)) |
| return tcu::TestStatus::fail("Failed"); |
| } |
| |
| return tcu::TestStatus::pass("Passed"); |
| } |
| |
| /******** 19.2. Command Buffer Lifetime (5.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 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 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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // 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); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| // 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)); |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < LARGE_BUFFER_SIZE; ++ndx) |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice)))); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // 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); |
| } |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| // 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 Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // Put the command buffer in recording state. |
| beginCommandBuffer(vk, *cmdBuf, 0u); |
| { |
| // Set the event |
| vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| endCommandBuffer(vk, *cmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.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. |
| beginCommandBuffer(vk, *cmdBuf, 0u); |
| endCommandBuffer(vk, *cmdBuf); |
| |
| // Submit the command buffer after resetting. It should have no commands |
| // recorded, so the event should remain unsignaled. |
| submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get()); |
| |
| // 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."); |
| } |
| |
| using de::SharedPtr; |
| typedef SharedPtr<Unique<VkEvent> > VkEventShared; |
| |
| template<typename T> |
| inline SharedPtr<Unique<T> > makeSharedPtr (Move<T> move) |
| { |
| return SharedPtr<Unique<T> >(new Unique<T>(move)); |
| } |
| |
| bool submitAndCheck (Context& context, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const Unique<VkFence> fence (createFence(vk, vkDevice)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| static_cast<deUint32>(cmdBuffers.size()), // commandBufferCount |
| &cmdBuffers[0], // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence.get())); |
| VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), 0u, INFINITE_TIMEOUT)); |
| |
| for(int eventNdx = 0; eventNdx < static_cast<int>(events.size()); ++eventNdx) |
| { |
| if (vk.getEventStatus(vkDevice, **events[eventNdx]) != VK_EVENT_SET) |
| return false; |
| vk.resetEvent(vkDevice, **events[eventNdx]); |
| } |
| |
| return true; |
| } |
| |
| void createCommadBuffers (const DeviceInterface& vk, |
| const VkDevice vkDevice, |
| deUint32 bufferCount, |
| VkCommandPool pool, |
| const VkCommandBufferLevel cmdBufferLevel, |
| VkCommandBuffer* pCommandBuffers) |
| { |
| const VkCommandBufferAllocateInfo cmdBufParams = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| pool, // VkCommandPool pool; |
| cmdBufferLevel, // VkCommandBufferLevel level; |
| bufferCount, // uint32_t bufferCount; |
| }; |
| VK_CHECK(vk.allocateCommandBuffers(vkDevice, &cmdBufParams, pCommandBuffers)); |
| } |
| |
| void addCommandsToBuffer (const DeviceInterface& vk, std::vector<VkCommandBuffer>& cmdBuffers, std::vector <VkEventShared>& events) |
| { |
| 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 cmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // flags |
| &secCmdBufInheritInfo, // pInheritanceInfo; |
| }; |
| |
| for(int bufferNdx = 0; bufferNdx < static_cast<int>(cmdBuffers.size()); ++bufferNdx) |
| { |
| VK_CHECK(vk.beginCommandBuffer(cmdBuffers[bufferNdx], &cmdBufBeginInfo)); |
| vk.cmdSetEvent(cmdBuffers[bufferNdx], **events[bufferNdx % events.size()], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| endCommandBuffer(vk, cmdBuffers[bufferNdx]); |
| } |
| } |
| |
| bool executeSecondaryCmdBuffer (Context& context, |
| VkCommandPool pool, |
| std::vector<VkCommandBuffer>& cmdBuffersSecondary, |
| std::vector <VkEventShared>& events) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| std::vector<VkCommandBuffer> cmdBuffer (1); |
| |
| createCommadBuffers(vk, vkDevice, 1u, pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, &cmdBuffer[0]); |
| beginCommandBuffer(vk, cmdBuffer[0], 0u); |
| vk.cmdExecuteCommands(cmdBuffer[0], static_cast<deUint32>(cmdBuffersSecondary.size()), &cmdBuffersSecondary[0]); |
| endCommandBuffer(vk, cmdBuffer[0]); |
| |
| bool returnValue = submitAndCheck(context, cmdBuffer, events); |
| vk.freeCommandBuffers(vkDevice, pool, 1u, &cmdBuffer[0]); |
| return returnValue; |
| } |
| |
| tcu::TestStatus trimCommandPoolTest (Context& context, const VkCommandBufferLevel cmdBufferLevel) |
| { |
| if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1")) |
| TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); |
| |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| |
| //test parameters |
| const deUint32 cmdBufferIterationCount = 300u; |
| const deUint32 cmdBufferCount = 10u; |
| |
| 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)); |
| |
| std::vector <VkEventShared> events; |
| for (deUint32 ndx = 0u; ndx < cmdBufferCount; ++ndx) |
| events.push_back(makeSharedPtr(createEvent(vk, vkDevice))); |
| |
| { |
| std::vector<VkCommandBuffer> cmdBuffers(cmdBufferCount); |
| createCommadBuffers(vk, vkDevice, cmdBufferCount, *cmdPool, cmdBufferLevel, &cmdBuffers[0]); |
| |
| for (deUint32 cmdBufferIterationrNdx = 0; cmdBufferIterationrNdx < cmdBufferIterationCount; ++cmdBufferIterationrNdx) |
| { |
| addCommandsToBuffer(vk, cmdBuffers, events); |
| |
| //Peak, situation when we use a lot more command buffers |
| if (cmdBufferIterationrNdx % 10u == 0) |
| { |
| std::vector<VkCommandBuffer> cmdBuffersPeak(cmdBufferCount * 10u); |
| createCommadBuffers(vk, vkDevice, static_cast<deUint32>(cmdBuffersPeak.size()), *cmdPool, cmdBufferLevel, &cmdBuffersPeak[0]); |
| addCommandsToBuffer(vk, cmdBuffersPeak, events); |
| |
| switch(cmdBufferLevel) |
| { |
| case VK_COMMAND_BUFFER_LEVEL_PRIMARY: |
| if (!submitAndCheck(context, cmdBuffersPeak, events)) |
| return tcu::TestStatus::fail("Fail"); |
| break; |
| case VK_COMMAND_BUFFER_LEVEL_SECONDARY: |
| if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffersPeak, events)) |
| return tcu::TestStatus::fail("Fail"); |
| break; |
| default: |
| DE_ASSERT(0); |
| } |
| vk.freeCommandBuffers(vkDevice, *cmdPool, static_cast<deUint32>(cmdBuffersPeak.size()), &cmdBuffersPeak[0]); |
| } |
| |
| vk.trimCommandPool(vkDevice, *cmdPool, (VkCommandPoolTrimFlags)0); |
| |
| switch(cmdBufferLevel) |
| { |
| case VK_COMMAND_BUFFER_LEVEL_PRIMARY: |
| if (!submitAndCheck(context, cmdBuffers, events)) |
| return tcu::TestStatus::fail("Fail"); |
| break; |
| case VK_COMMAND_BUFFER_LEVEL_SECONDARY: |
| if (!executeSecondaryCmdBuffer(context, *cmdPool, cmdBuffers, events)) |
| return tcu::TestStatus::fail("Fail"); |
| break; |
| default: |
| DE_ASSERT(0); |
| } |
| |
| for (deUint32 bufferNdx = cmdBufferIterationrNdx % 3u; bufferNdx < cmdBufferCount; bufferNdx+=2u) |
| { |
| vk.freeCommandBuffers(vkDevice, *cmdPool, 1u, &cmdBuffers[bufferNdx]); |
| createCommadBuffers(vk, vkDevice, 1u, *cmdPool, cmdBufferLevel, &cmdBuffers[bufferNdx]); |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("Pass"); |
| } |
| |
| /******** 19.3. Command Buffer Recording (5.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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| endCommandBuffer(vk, *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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // 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); |
| }; |
| |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| 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, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // record primary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| // record setting event |
| vk.cmdSetEvent(*secCmdBuf, *event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| endCommandBuffer(vk, *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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // 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); |
| }; |
| |
| |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| 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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // 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); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.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)); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| // 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 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, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record first primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf1, 0u); |
| { |
| // 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 |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBuf1); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.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 |
| beginCommandBuffer(vk, *primCmdBuf2, 0u); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get()); |
| } |
| // end recording |
| endCommandBuffer(vk, *primCmdBuf2); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get()); |
| |
| // 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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf); |
| { |
| // 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); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.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 |
| beginCommandBuffer(vk, *primCmdBuf); |
| { |
| // 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); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| // 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 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, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> event (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *event)); |
| |
| // record first primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf1, 0u); |
| { |
| // 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 |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf1, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBuf1); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf1.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 |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // record second primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf2, 0u); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf2, 1, &secCmdBuf.get()); |
| } |
| // end recording |
| endCommandBuffer(vk, *primCmdBuf2); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf2.get()); |
| |
| // 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 renderPassContinueTest(Context& context) |
| { |
| const DeviceInterface& vkd = context.getDeviceInterface(); |
| CommandBufferRenderPassTestEnvironment env (context, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); |
| |
| VkCommandBuffer primaryCommandBuffer = env.getPrimaryCommandBuffer(); |
| VkCommandBuffer secondaryCommandBuffer = env.getSecondaryCommandBuffer(); |
| const deUint32 clearColor[4] = { 2, 47, 131, 211 }; |
| |
| const VkClearAttachment clearAttachment = |
| { |
| VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; |
| 0, // deUint32 colorAttachment; |
| makeClearValueColorU32(clearColor[0], |
| clearColor[1], |
| clearColor[2], |
| clearColor[3]) // VkClearValue clearValue; |
| }; |
| |
| const VkClearRect clearRect = |
| { |
| CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_AREA, // VkRect2D rect; |
| 0u, // deUint32 baseArrayLayer; |
| 1u // deUint32 layerCount; |
| }; |
| |
| env.beginSecondaryCommandBuffer(VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT); |
| vkd.cmdClearAttachments(secondaryCommandBuffer, 1, &clearAttachment, 1, &clearRect); |
| endCommandBuffer(vkd, secondaryCommandBuffer); |
| |
| |
| env.beginPrimaryCommandBuffer(0); |
| env.beginRenderPass(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); |
| vkd.cmdExecuteCommands(primaryCommandBuffer, 1, &secondaryCommandBuffer); |
| endRenderPass(vkd, primaryCommandBuffer); |
| |
| endCommandBuffer(vkd, primaryCommandBuffer); |
| |
| env.submitPrimaryCommandBuffer(); |
| |
| de::MovePtr<tcu::TextureLevel> result = env.readColorAttachment(); |
| tcu::PixelBufferAccess pixelBufferAccess = result->getAccess(); |
| |
| for (deUint32 i = 0; i < (CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.width * CommandBufferRenderPassTestEnvironment::DEFAULT_IMAGE_SIZE.height); ++i) |
| { |
| deUint8* colorData = reinterpret_cast<deUint8*>(pixelBufferAccess.getDataPtr()); |
| for (int colorComponent = 0; colorComponent < 4; ++colorComponent) |
| if (colorData[i * 4 + colorComponent] != clearColor[colorComponent]) |
| return tcu::TestStatus::fail("clear value mismatch"); |
| } |
| |
| return tcu::TestStatus::pass("render pass continue test passed"); |
| } |
| |
| 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)); |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> eventOne (createEvent(vk, vkDevice)); |
| const Unique<VkEvent> eventTwo (createEvent(vk, vkDevice)); |
| |
| // reset event |
| VK_CHECK(vk.resetEvent(vkDevice, *eventOne)); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); |
| { |
| // wait for event |
| vk.cmdWaitEvents(*primCmdBuf, 1u, &eventOne.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); |
| |
| // Set the second event |
| vk.cmdSetEvent(*primCmdBuf, eventTwo.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence1 (createFence(vk, vkDevice)); |
| const Unique<VkFence> fence2 (createFence(vk, vkDevice)); |
| |
| 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 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, |
| }; |
| |
| // create event that will be used to check if secondary command buffer has been executed |
| const Unique<VkEvent> eventOne (createEvent(vk, vkDevice)); |
| const Unique<VkEvent> eventTwo (createEvent(vk, vkDevice)); |
| |
| // 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 |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // execute secondary buffer |
| vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice)); |
| |
| 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 simultaneousUseSecondaryBufferOnePrimaryBufferTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| Allocator& allocator = context.getDefaultAllocator(); |
| const ComputeInstanceResultBuffer result(vk, vkDevice, allocator, 0.0f); |
| |
| 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 VkCommandBufferInheritanceInfo secCmdBufInheritInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, |
| DE_NULL, |
| (VkRenderPass)0u, |
| 0u, // subpass |
| (VkFramebuffer)0u, |
| VK_FALSE, // occlusionQueryEnable |
| (VkQueryControlFlags)0u, |
| (VkQueryPipelineStatisticFlags)0u, |
| }; |
| const VkCommandBufferBeginInfo secCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| DE_NULL, |
| VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, // flags |
| &secCmdBufInheritInfo, |
| }; |
| |
| const deUint32 offset = (0u); |
| const deUint32 addressableSize = 256; |
| const deUint32 dataSize = 8; |
| de::MovePtr<Allocation> bufferMem; |
| const Unique<VkBuffer> buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem)); |
| // Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute |
| const Unique<VkDescriptorSetLayout> descriptorSetLayout(createDescriptorSetLayout(context)); |
| const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(context)); |
| const Unique<VkDescriptorSet> descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer())); |
| 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, vkDevice, &layoutCreateInfo)); |
| |
| const Unique<VkShaderModule> computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u)); |
| |
| const VkPipelineShaderStageCreateInfo shaderCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
| DE_NULL, |
| (VkPipelineShaderStageCreateFlags)0, |
| VK_SHADER_STAGE_COMPUTE_BIT, // stage |
| *computeModule, // shader |
| "main", |
| DE_NULL, // pSpecializationInfo |
| }; |
| |
| const VkComputePipelineCreateInfo pipelineCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| shaderCreateInfo, // cs |
| *pipelineLayout, // layout |
| (vk::VkPipeline)0, // basePipelineHandle |
| 0u, // basePipelineIndex |
| }; |
| |
| const Unique<VkPipeline> pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo)); |
| |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); |
| vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0); |
| vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u); |
| } |
| // end recording of secondary buffer |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // record primary command buffer |
| beginCommandBuffer(vk, *primCmdBuf, 0u); |
| { |
| // execute secondary buffer twice in same primary |
| vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get()); |
| vk.cmdExecuteCommands(*primCmdBuf, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBuf); |
| |
| submitCommandsAndWait(vk, vkDevice, queue, primCmdBuf.get()); |
| |
| deUint32 resultCount; |
| result.readResultContentsTo(&resultCount); |
| // check if secondary buffer has been executed |
| if (resultCount == 2) |
| return tcu::TestStatus::pass("Simulatous Secondary Command Buffer Execution succeeded"); |
| else |
| return tcu::TestStatus::fail("Simulatous Secondary Command Buffer Execution FAILED"); |
| } |
| |
| tcu::TestStatus simultaneousUseSecondaryBufferTwoPrimaryBuffersTest(Context& context) |
| { |
| const VkDevice vkDevice = context.getDevice(); |
| const DeviceInterface& vk = context.getDeviceInterface(); |
| const VkQueue queue = context.getUniversalQueue(); |
| const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); |
| Allocator& allocator = context.getDefaultAllocator(); |
| const ComputeInstanceResultBuffer result(vk, vkDevice, allocator, 0.0f); |
| |
| 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; |
| }; |
| // Two separate primary cmd buffers that will be executed with the same secondary cmd buffer |
| const deUint32 numPrimCmdBufs = 2; |
| const Unique<VkCommandBuffer> primCmdBufOne(allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const Unique<VkCommandBuffer> primCmdBufTwo(allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| VkCommandBuffer primCmdBufs[numPrimCmdBufs]; |
| primCmdBufs[0] = primCmdBufOne.get(); |
| primCmdBufs[1] = primCmdBufTwo.get(); |
| |
| // 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, |
| }; |
| |
| const deUint32 offset = (0u); |
| const deUint32 addressableSize = 256; |
| const deUint32 dataSize = 8; |
| de::MovePtr<Allocation> bufferMem; |
| const Unique<VkBuffer> buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem)); |
| // Secondary command buffer will have a compute shader that does an atomic increment to make sure that all instances of secondary buffers execute |
| const Unique<VkDescriptorSetLayout> descriptorSetLayout(createDescriptorSetLayout(context)); |
| const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(context)); |
| const Unique<VkDescriptorSet> descriptorSet(createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer())); |
| 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, vkDevice, &layoutCreateInfo)); |
| |
| const Unique<VkShaderModule> computeModule(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("compute_increment"), (VkShaderModuleCreateFlags)0u)); |
| |
| const VkPipelineShaderStageCreateInfo shaderCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
| DE_NULL, |
| (VkPipelineShaderStageCreateFlags)0, |
| VK_SHADER_STAGE_COMPUTE_BIT, // stage |
| *computeModule, // shader |
| "main", |
| DE_NULL, // pSpecializationInfo |
| }; |
| |
| const VkComputePipelineCreateInfo pipelineCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, |
| DE_NULL, |
| 0u, // flags |
| shaderCreateInfo, // cs |
| *pipelineLayout, // layout |
| (vk::VkPipeline)0, // basePipelineHandle |
| 0u, // basePipelineIndex |
| }; |
| |
| const Unique<VkPipeline> pipeline(createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo)); |
| |
| // record secondary command buffer |
| VK_CHECK(vk.beginCommandBuffer(*secCmdBuf, &secCmdBufBeginInfo)); |
| { |
| vk.cmdBindPipeline(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); |
| vk.cmdBindDescriptorSets(*secCmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, numDescriptorSets, descriptorSets, 0, 0); |
| vk.cmdDispatch(*secCmdBuf, 1u, 1u, 1u); |
| } |
| // end recording of secondary buffer |
| endCommandBuffer(vk, *secCmdBuf); |
| |
| // record primary command buffers |
| // Insert one instance of same secondary command buffer into two separate primary command buffers |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBufOne, &primCmdBufBeginInfo)); |
| { |
| vk.cmdExecuteCommands(*primCmdBufOne, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBufOne); |
| |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBufTwo, &primCmdBufBeginInfo)); |
| { |
| vk.cmdExecuteCommands(*primCmdBufTwo, 1, &secCmdBuf.get()); |
| } |
| endCommandBuffer(vk, *primCmdBufTwo); |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence(createFence(vk, vkDevice)); |
| |
| const VkSubmitInfo submitInfo = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask |
| numPrimCmdBufs, // commandBufferCount |
| primCmdBufs, // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // submit primary buffers, the secondary should be executed too |
| 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)); |
| |
| deUint32 resultCount; |
| result.readResultContentsTo(&resultCount); |
| // check if secondary buffer has been executed |
| if (resultCount == 2) |
| 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(); |
| |
| if (!context.getDeviceFeatures().inheritedQueries) |
| TCU_THROW(NotSupportedError, "Inherited queries feature is not supported"); |
| |
| 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, |
| }; |
| |
| const VkQueryPoolCreateInfo queryPoolCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType |
| DE_NULL, // pNext |
| (VkQueryPoolCreateFlags)0, // flags |
| VK_QUERY_TYPE_OCCLUSION, // queryType |
| 1u, // entryCount |
| 0u, // pipelineStatistics |
| }; |
| Unique<VkQueryPool> queryPool (createQueryPool(vk, vkDevice, &queryPoolCreateInfo)); |
| |
| VK_CHECK(vk.beginCommandBuffer(secCmdBuf.get(), &secBufferBeginInfo)); |
| endCommandBuffer(vk, 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); |
| } |
| endCommandBuffer(vk, 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(); |
| |
| if (!context.getDeviceFeatures().inheritedQueries) |
| TCU_THROW(NotSupportedError, "Inherited queries feature is not supported"); |
| |
| 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)); |
| endCommandBuffer(vk, 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); |
| } |
| endCommandBuffer(vk, 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(); |
| |
| if (!context.getDeviceFeatures().inheritedQueries) |
| TCU_THROW(NotSupportedError, "Inherited queries feature is not supported"); |
| |
| 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)); |
| endCommandBuffer(vk, 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); |
| } |
| endCommandBuffer(vk, primCmdBuf.get()); |
| |
| return tcu::TestStatus::pass("Successfully recorded a secondary command buffer allowing a precise occlusion query."); |
| } |
| |
| /******** 19.4. Command Buffer Submission (5.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, |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| { |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice)))); |
| } |
| |
| // 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); |
| } |
| endCommandBuffer(vk, cmdBuffers[ndx]); |
| } |
| |
| // We'll use a fence to wait for the execution of the queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice)); |
| |
| 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, |
| }; |
| |
| std::vector<VkEventSp> events; |
| for (deUint32 ndx = 0; ndx < BUFFER_COUNT; ++ndx) |
| events.push_back(VkEventSp(new vk::Unique<VkEvent>(createEvent(vk, vkDevice)))); |
| |
| // 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); |
| } |
| endCommandBuffer(vk, cmdBuffers[ndx]); |
| } |
| |
| // We'll use a fence to wait for the execution of the queue |
| const Unique<VkFence> fenceZero (createFence(vk, vkDevice)); |
| const Unique<VkFence> fenceOne (createFence(vk, vkDevice)); |
| |
| 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 submitBufferWaitSingleSemaphore(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; |
| }; |
| |
| // Create two command buffers |
| const Unique<VkCommandBuffer> primCmdBuf1 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| const Unique<VkCommandBuffer> primCmdBuf2 (allocateCommandBuffer(vk, vkDevice, &cmdBufParams)); |
| |
| const VkCommandBufferBeginInfo primCmdBufBeginInfo = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType |
| DE_NULL, // pNext |
| 0, // flags |
| DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; |
| }; |
| |
| // create two events that will be used to check if command buffers has been executed |
| const Unique<VkEvent> event1 (createEvent(vk, vkDevice)); |
| const Unique<VkEvent> event2 (createEvent(vk, vkDevice)); |
| |
| // reset events |
| VK_CHECK(vk.resetEvent(vkDevice, *event1)); |
| VK_CHECK(vk.resetEvent(vkDevice, *event2)); |
| |
| // record first command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf1, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf1, *event1,stageMask); |
| } |
| endCommandBuffer(vk, *primCmdBuf1); |
| |
| // record second command buffer |
| VK_CHECK(vk.beginCommandBuffer(*primCmdBuf2, &primCmdBufBeginInfo)); |
| { |
| // allow execution of event during every stage of pipeline |
| VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| // record setting event |
| vk.cmdSetEvent(*primCmdBuf2, *event2,stageMask); |
| } |
| endCommandBuffer(vk, *primCmdBuf2); |
| |
| // create fence to wait for execution of queue |
| const Unique<VkFence> fence (createFence(vk, vkDevice)); |
| |
| // create semaphore for use in this test |
| const Unique <VkSemaphore> semaphore (createSemaphore(vk, vkDevice)); |
| |
| // create submit info for first buffer - signalling semaphore |
| const VkSubmitInfo submitInfo1 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 0u, // waitSemaphoreCount |
| DE_NULL, // pWaitSemaphores |
| DE_NULL, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf1.get(), // pCommandBuffers |
| 1u, // signalSemaphoreCount |
| &semaphore.get(), // pSignalSemaphores |
| }; |
| |
| // Submit the command buffer to the queue |
| 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)); |
| |
| // check if buffer has been executed |
| VkResult result = vk.getEventStatus(vkDevice,*event1); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED"); |
| |
| const VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; |
| |
| // create submit info for second buffer - waiting for semaphore |
| const VkSubmitInfo submitInfo2 = |
| { |
| VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType |
| DE_NULL, // pNext |
| 1u, // waitSemaphoreCount |
| &semaphore.get(), // pWaitSemaphores |
| &waitDstStageFlags, // pWaitDstStageMask |
| 1, // commandBufferCount |
| &primCmdBuf2.get(), // pCommandBuffers |
| 0u, // signalSemaphoreCount |
| DE_NULL, // pSignalSemaphores |
| }; |
| |
| // reset fence, so it can be used again |
| VK_CHECK(vk.resetFences(vkDevice, 1u, &fence.get())); |
| |
| // Submit the second command buffer to the queue |
| 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 second buffer has been executed |
| // if it has been executed, it means that the semaphore was signalled - so test if passed |
| result = vk.getEventStatus(vkDevice,*event1); |
| if (result != VK_EVENT_SET) |
| return tcu::TestStatus::fail("Submit Buffer and Wait for Single Semaphore Test FAILED"); |
| |
| return tcu::TestStatus::pass("Submit Buffer and Wait for Single Semaphore Test succeeded"); |
| } |
| |
| tcu::TestStatus submitBufferWaitManySemaphores(Context& context) |
| { |
| // This test will create numSemaphores semaphores, and signal them in NUM_SEMAPHORES submits to queue |
| // After that the numSubmissions queue submissions will wait for each semaphore |
| |
| const deUint32 numSemaphores = 10u; // it must be multiply of numSubmission |
| const deUint32 numSubmissions = 2u; |
| 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, |