From 7a598c95f3ecf8a209e733b704c51ea87db12c53 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20=C5=81ebski?= Date: Tue, 10 Nov 2015 18:33:15 +0100 Subject: [PATCH] Draft of test spec for Command Buffers. Fixed two typos pointed out in the merge request review. Minor updates and fixes for Command Buffers test spec: 1. Split that one big table into several smaller ones, corresponding to chapters in Vulkan's spec. 2. Added placeholders for missing testspecs - allowed commands and render pass Fixed colum width in Command Buffer testspec First part of Render Pass test spec. 1. Replaced repeating parts of lengthy descriptions fir ellipses for the sake of clarity. 2. Added three more test case descriptions. Added the remaining validity tests for structures used while creating render passes. Added testcases for Render Pass destruction. This concludes the test spec for Render Pass. Framebuffer testcases covered. Fixed an error with numbering testcases for Framebuffers Fixed command buffer test spec according to Alon's pointers. 1. Removed A LOT of testcases that would result in undefined behaviour. 2. Added a number of testcases to better cover possible uses of the command buffer API 3. Cleaned up the section of the document related to command buffers added first command buffer test, fix to nexus compilation added test for secondary commnad buffers execution - currently crashing 1. Command Buffer lifetime tests - explicit reset - implicit reset - bulk reset 2. Pulled the timeout variable out and made it a global (did not modify code in first two test cases) Updated the test spec according to API v170.2 Fixed style errors in test cases related to resetting command buffers. order of execution test - first 1. Added CK_CHECK whenever possible 2. Minor formatting fixes 3. Removed several redundance vk:: uses 4. Switched from using wrapper methods to direct calls to DeviceInterface's methods when more than one buffer and event are needed. --- doc/testspecs/VK/apitests.adoc | 139 +++- external/vulkancts/build_spirv_binaries.py | 2 +- .../modules/vulkan/api/BufferComputeInstance.cpp | 194 +++++ .../modules/vulkan/api/BufferComputeInstance.hpp | 75 ++ .../vulkancts/modules/vulkan/api/CMakeLists.txt | 6 + .../vulkan/api/ComputeInstanceResultBuffer.cpp | 116 +++ .../vulkan/api/ComputeInstanceResultBuffer.hpp | 102 +++ .../vulkan/api/vktApiCommandBuffersTests.cpp | 863 +++++++++++++++++++++ .../vulkan/api/vktApiCommandBuffersTests.hpp | 51 ++ .../vulkancts/modules/vulkan/api/vktApiTests.cpp | 3 +- framework/platform/android/tcuAndroidPlatform.cpp | 2 +- targets/android/android.cmake | 4 +- 12 files changed, 1548 insertions(+), 9 deletions(-) create mode 100644 external/vulkancts/modules/vulkan/api/BufferComputeInstance.cpp create mode 100644 external/vulkancts/modules/vulkan/api/BufferComputeInstance.hpp create mode 100644 external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.cpp create mode 100644 external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.hpp create mode 100644 external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp create mode 100644 external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.hpp diff --git a/doc/testspecs/VK/apitests.adoc b/doc/testspecs/VK/apitests.adoc index bbc2a70..b18df28 100644 --- a/doc/testspecs/VK/apitests.adoc +++ b/doc/testspecs/VK/apitests.adoc @@ -94,7 +94,7 @@ tcu::TestStatus createSamplerTest (Context& context) tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) { de::MovePtr apiTests (new tcu::TestCaseGroup(testCtx, "api", "API Tests")); - + addFunctionCase(apiTests.get(), "create_sampler", "", createSamplerTest); return apiTests.release(); @@ -2406,7 +2406,60 @@ VkResult VKAPI vkResetCommandBuffer( VkCmdBufferResetFlags flags); ---- -Command pools +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Secondary buffers execution | Check if secondary command buffers are executed | Secondary command buffers may be called from primary command buffers, and are not directly submitted to queues. +|2 | Order of execution | Check if commands that should be executed in-order are indeed done so. | Some command buffer commands are described as executing in-order with respect to other commands. This means that the effect of that one command must happen in the same order, relative to these other commands, as the order they were added to the command buffer. +|3 | Synchronization | The commands may end in different order then they are being executed. Using semaphores for synchronization should prevent this | Unless otherwise specified, and without explicit synchronization, the various commands submitted to a queue via command buffers may execute in arbitrary order relative to each other, and/or concurrently. Also, the memory side-effects of those commands may not be directly visible to other commands without memory barriers. This is true within a command buffer, and across command buffers submitted to a given queue. See topic about synchronization primitives suitable to guarantee execution order and side-effect visibility between commands on a given queue. +|4 | Independent state between buffers | Execute secondary command buffer, change state of primary, execute secondary again, and check if its state was changed | When secondary command buffer(s) are recorded to execute on a primary command buffer, the secondary command buffer inherits no state from the primary command buffer, and all state of the primary command buffer is undefined after an execute secondary command buffer command is recorded. +|5 | Renderpass state independence | State inside a renderpass should not be changed by executing secondary command buffers | If the primary command buffer is inside a renderpass, then the renderpass and subpass state is not disturbed by executing secondary command buffers +|=== + +Command Buffer lifetime +~~~~~~~~~~~~~~~~~~~~~~~ + +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Resetting command buffers - explicitly | Reset a command buffer using vkResetCommandBuffer | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT controls whether command buffers allocated from the pool can be individually reset. If this flag is set, individual command buffers allocated from the pool can be reset either explicitly, by calling vkResetCommandBuffer, or implicitly, by calling vkBeginCommandBuffer on a recorded command buffer. If this flag is not set, then the command buffers may only be reset in bulk by calling vkResetCommandPool. +|2 | Resetting command buffers - implicitly | Reset a command buffer by calling vkBeginCommandBuffer on a buffer that has already been recorded | +|3 | Resetting command buffers - bulk | Reset two command buffers that have already been recorded by calling vkResetCommandPool on the pool the command buffers were created from | +|=== + +Command Buffer recording +~~~~~~~~~~~~~~~~~~~~~~~~ + +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Recording to buffers | Check if all functions that should be recorded, are recorded | +|2 | Render pass ignoring | if VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT flag is not set, the values of renderPass, framebuffer, and subpass members of the VkCommandBufferBeginInfo should be ignored | If flags has VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT set, the entire secondary command buffer is considered inside a render pass. In this case, the renderPass, framebuffer, and subpass members of the VkCommandBufferBeginInfo structure must be set as described below. Otherwise the renderPass, framebuffer, and subpass members of the VkCommandBufferBeginInfo structure are ignored, and the secondary command buffer may not contain commands that are only allowed inside a render pass. +|3 | Simultaneous use – primary buffers | Set flag VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT and submit two times simultanously | If flags does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set, the command buffer must not be pending execution more than once at any given time. A primary command buffer is considered to be pending execution from the time it is submitted via vkQueueSubmit until that submission completes. +|4 | Simultaneous use – secondary buffers | Set VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT on secondary buffer, and use the secondary buffer twice in primary buffer | If VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT is not set on a secondary command buffer, that command buffer cannot be used more than once in a given primary command buffer. +|5 | Patch in place | Do not set VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT and check if buffer can be patched in-place | On some implementations, not using the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT bit enables command buffers to be patched in-place if needed, rather than creating a copy of the command buffer. +|6 | Improper recording | call vkBeginCommandBuffer on buffer currently recording – vkEndCommandBuffer should return error | It is invalid to begin a command buffer while it is being recorded +|7 | | call vkEndCommandBuffer on buffer that is not recording – vkEndCommandBuffer should return error | It is invalid to end a command buffer if it is not being recorded. +|8 | | call vkResetCommandBuffer on buffer currently recording – vkEndCommandBuffer should return error | It is invalid to reset a command buffer while it is being recorded. +|9 | | vkBeginCommandBuffer on buffer already recorded, that has no VK_COMMAND_POOL_RESET_COMMAND_BUFFER_BIT flag set – vkEndCommandBuffer should return error | It is invalid to begin a command buffer that has already been recorded if the command buffer was allocated from a command pool that did not have the VK_COMMAND_POOL_RESET_COMMAND_BUFFER_BIT flag set until vkResetCommandPool is called on the pool +|10 | | Make any of improper recording tests, reset the buffer and check if after the reset it starts recording correctly | If there was an error during recording, the application will by notified by an unsuccessful return code returned by vkEndCommandBuffer. If the application wishes to further use the command buffer, the command buffer must be reset. +|=== + +Command Buffer submission +~~~~~~~~~~~~~~~~~~~~~~~~~ + +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Submission correctness | Call vkQueueSubmit with submitCount equal to the actual count of submits | pSubmits must be an array of submitCount valid VkSubmitInfo structures. If submitCount is 0 though, pSubmits is ignored +|2 | | ... submitCount == 0 | +|3 | queue and fence origin | Call vkQueueSubmit with queue and fence that were created from the same VkDevice | queue and fence must have been created, allocated or retrieved from the same VkDevice +|4 | | Call vkQueueSubmit with queue and fence that were allocated from the same VkDevice | +|5 | | Call vkQueueSubmit with queue and fence that were retrieved from the same VkDevice | +|6 | Fence validity | Call vkQueueSubmit with VK_NULL_HANDLE passed as fence. | If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle +|=== + +Command Pools ~~~~~~~~~~~~~ TODO @@ -2442,8 +2495,14 @@ VkResult VKAPI vkResetCommandPool( VkCmdPoolResetFlags flags); ---- -2-level command buffers -~~~~~~~~~~~~~~~~~~~~~~~ +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Create, Reset and Destroy a Command Pool | Simple usage test. Create command pool, reset it, and destroy it. Check if result is success. | +|=== + +Secondary Command Buffers +~~~~~~~~~~~~~~~~~~~~~~~~~ TODO @@ -2455,6 +2514,78 @@ void VKAPI vkCmdExecuteCommands( const VkCmdBuffer* pCmdBuffers); ---- +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Buffers' origin | Call vkCmdExecuteCommands with commandBuffer and pCommandBuffers that created from the same VkDevice | commandBuffer and pCommandBuffers must have been created, allocated or retrieved from the same VkDevice +|2 | | ... allocated from the same VkDevice | +|3 | | ... retrieved from the same VkDevice | +|4 | Simultaneous use | Call vkCmdExecuteCommands with pCommandBuffers such that its element is already pending execution in commandBuffer and was created with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag | Any given element of pCommandBuffers must not be already pending execution in commandBuffer, or appear twice in pCommandBuffers, unless it was created with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag +|5 | | Call vkCmdExecuteCommands with pCommandBuffers such that its element appears twice in pCommandBuffers and was created with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag | +|6 | Call from within a VkRenderPass | Call vkCmdExecuteCommands within a VkRenderPass with all elements of pCommandBuffers recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | If vkCmdExecuteCommands is being called within a VkRenderPass, any given element of pCommandBuffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT +|=== + +Render Pass +~~~~~~~~~~~ + +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Attachment count in pCreateInfo | Call vkCreateRenderPass with pCreateInfo such that attachmentCount is equal to the number of attachments | pAttachments must be an array of attachmentCount valid VkSubpassDependency structures. If attachmentCount is 0 though, pAttachments is ignored +|2 | | ... attachmentCount = 0 | +|3 | Dependency count in pCreateInfo | Call vkCreateRenderPass with pCreateInfo such that dependencyCount is equal to the number of dependencies | pDependencies must be an array of dependencyCount valid VkSubpassDependency structures. If dependencyCount is 0 though, pDependencies is ignored +|4 | | ... dependencyCount = 0 | +|5 | Subpass dependency | Call vkCreateRenderPass with pCreateInfo pointing at a VkRenderPassCreateInfo structure with any two subpasses operating on attachments with overlapping ranges of the same VkDeviceMemory object and at least one of the writing to that area of VkDeviceMemory with a subpass dependency included directly | If any two subpasses operate on attachments with overlapping ranges of the same VkDeviceMemory object, and at least one subpass writes to that area of VkDeviceMemory, a subpass dependency must be included (either directly or via some intermediate subpasses) between them +|6 | | ... with a subpass dependency included via intermediate subpasses | +|7 | Attachments in subpasses | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where the attachment member of an element of pInputAttachments in an element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with a different attachment in a subpass and the VkAttachmentReference structure describing said element includes VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS bit in flags | If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments, pDepthStencilAttachment, or pPreserveAttachments in any given element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with any other attachment in any subpass (including the same subpass), the VkAttachmentReference structures describing them must include VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in flags +|8 | | ... the attachment member of an element of pColorAttachments ... | +|9 | | ... the attachment member of an element of pResolveAttachments ... | +|10 | | ... the attachment member of an element of pDepthStencilAttachment ... | +|11 | | ... the attachment member of an element of pPreserveAttachments ... | +|12 | | ... the attachment member of an element of pInputAttachments in any given element of pSubpasses is not VK_ATTACHMENT_UNUSED and is less than the value of attachmentCount | If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments, pDepthStencilAttachment, or pPreserveAttachments in any given element of pSubpasses is not VK_ATTACHMENT_UNUSED, it must be less than the value of attachmentCount +|13 | | ... the attachment member of an element of pColorAttachments ... | +|14 | | ... the attachment member of an element of pResolveAttachments ... | +|15 | | ... the attachment member of an element of pDepthStencilAttachment ... | +|16 | | ... the attachment member of an element of pPreserveAttachments ... | +|17 | Subpass description | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where inputAttachmentCount is equal to the actual count of input attachments | pInputAttachments must be an array of inputAttachmentCount valid VkAttachmentReference structures. If inputAttachmentCount is 0 though, pInputAttachments is ignored +|18 | | ... inputAttachmentCount == 0 | +|19 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where colorAttachmentCount is equal to the actual count of color attachments | pColorAttachments must be an array of colorAttachmentCount valid VkAttachmentReference structures. If colorAttachmentCount is 0 though, pColorAttachments is ignored +|20 | | ... colorAttachmentCount == 0 | +|21 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where pResolveAttachments is not NULL and colorAttachmentCount is equal to the actual count of resolve attachments | If pResolveAttachments is not NULL, pResolveAttachments must be an array of colorAttachmentCount valid VkAttachmentReference structures. If colorAttachmentCount is 0 though, pResolveAttachments is ignored +|22 | | ... pResolveAttachments is not NULL and colorAttachmentCount == 0 | +|23 | | ... pResolveAttachments is NULL | +|24 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where pDepthStencilAttachment points at a valid VkAttachmentReference structure | If pDepthStencilAttachment is not NULL, pDepthStencilAttachment must be a pointer to a valid VkAttachmentReference structure +|25 | | ... pDepthStencilAttachment is NULL | +|26 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where preserveAttachmentCount is equal to the actual count of preserveAttachments | pPreserveAttachments must be an array of preserveAttachmentCount valid VkAttachmentReference structures. If preserveAttachmentCount is 0 though, pPreserveAttachments is ignored +|27 | | ... preserveAttachmentCount == 0 | +|28 | | | he value of colorCount must be less than or equal to VkPhysicalDeviceLimits::maxColorAttachments +|29 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where no depth nor stencil attachment is used and pDepthStencil == NULL | If no depth/stencil attachment is used in the subpass, pDepthStencil must be NULL, or the attachment member of a given element of pDepthStencil must be VK_ATTACHMENT_UNUSED +|30 | | ... and pDepthStencil == VK_ATTACHMENT_UNUSED | +|31 | | ... Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where pResolveAttachments is not NULL and for each resolve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment does not have the value VK_ATTACHMENT_UNUSED either | If pResolveAttachments is not NULL, for each resolve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment must not have the value VK_ATTACHMENT_UNUSED +|32 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where pResolveAttachments is not NULL and the sample count of each element of pColorAttachments is different than VK_SAMPLE_COUNT_1_BIT | If pResolveAttachments is not NULL, the sample count of each element of pColorAttachments must be anything other than VK_SAMPLE_COUNT_1_BIT +|33 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where two attachments referenced by pColorAttachments and pDepthStencilAttachment are not VK_ATTACHMENT_UNUSED and have the same sample count | All attachments referenced by pColorAttachments and pDepthStencilAttachment that are not VK_ATTACHMENT_UNUSED, must have the same sample count +|34 | | Call vkCreateRenderPass with pCreateInfo such that there is a subpass in pSubpasses where an input attachment is VK_ATTACHMENT_UNUSED and no pipelines bound during the subpass reference this input attachments | If any input attachments are VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must not reference those input attachments +|=== + +Framebuffers +~~~~~~~~~~~~~ + +[cols="1,4,8,8", options="header"] +|=== +|No. | Tested area | Test Description | Relevant specification text +|1 | Attachment count in pCreateInfo | Call vkCreateFramebuffer with pCreateInfo such that attachmentCount is equal to the number of attachments | pAttachments must be an array of attachmentCount valid VkImageView handles. If attachmentCount is 0 though, pAttachments is ignored +|2 | | ... where attachmentCount == 0 | +|3 | Render Pass and Attachments origin | Call vkCreateFramebuffer with pCreateInfo such that renderPass and pAttachments were created using the same VkDevice | renderPass and pAttachments must have been created, allocated or retrieved from the same VkDevice +|4 | | ... renderPass and pAttachments were allocated using the same VkDevice | +|5 | | ... renderPass and pAttachments were retrieved from the same VkDevice | +|6 | Dimensions | Call vkCreateFramebuffer with pCreateInfo such that width == 0 | The value of width must be less or equal to than VkPhysicalDeviceLimits::maxFramebufferWidth +|7 | | ... width == VkPhysicalDeviceLimits::maxFramebufferWidth | +|8 | | ... 0 < width < VkPhysicalDeviceLimits::maxFramebufferWidth | +|9 | | ... height == 0 | The value of height must be less or equal to than VkPhysicalDeviceLimits::maxFramebufferHeight +|10 | | ... height == VkPhysicalDeviceLimits::maxFramebufferHeight | +|11 | | ... 0 < height < VkPhysicalDeviceLimits::maxFramebufferHeight | +|=== + Draw commands ------------- diff --git a/external/vulkancts/build_spirv_binaries.py b/external/vulkancts/build_spirv_binaries.py index 8927f79..31b37d5 100644 --- a/external/vulkancts/build_spirv_binaries.py +++ b/external/vulkancts/build_spirv_binaries.py @@ -77,7 +77,7 @@ def execBuildPrograms (buildCfg, generator, module, mode, dstPath): try: binPath = generator.getBinaryPath(buildCfg.getBuildType(), os.path.join(".", "vk-build-programs")) - execute([binPath, "--mode", mode, "--dst-path", dstPath]) + subprocess.call([binPath, "--mode", mode, "--dst-path", dstPath]) finally: popWorkingDir() diff --git a/external/vulkancts/modules/vulkan/api/BufferComputeInstance.cpp b/external/vulkancts/modules/vulkan/api/BufferComputeInstance.cpp new file mode 100644 index 0000000..d2fa70d --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/BufferComputeInstance.cpp @@ -0,0 +1,194 @@ + +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + + + +#include "BufferComputeInstance.hpp" + +using namespace vk; +using tcu::TestLog; +using de::UniquePtr; + + +vk::VkDescriptorInfo createDescriptorInfo (vk::VkBuffer buffer, vk::VkDeviceSize offset, vk::VkDeviceSize range) +{ + const vk::VkDescriptorInfo resultInfo = + { + 0, // bufferView + 0, // sampler + 0, // imageView + (vk::VkImageLayout)0, // imageLayout + { buffer, offset, range } // bufferInfo + }; + return resultInfo; +}; + +vk::VkDescriptorInfo createDescriptorInfo (vk::VkBufferView bufferView) +{ + const vk::VkDescriptorInfo resultInfo = + { + bufferView, // bufferView + 0, // sampler + 0, // imageView + (vk::VkImageLayout)0, // imageLayout + { (vk::VkBuffer)0, 0, 0 } // bufferInfo + }; + return resultInfo; +}; + +vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler) +{ + const vk::VkDescriptorInfo resultInfo = + { + 0, // bufferView + sampler, // sampler + 0, // imageView + (vk::VkImageLayout)0, // imageLayout + { (vk::VkBuffer)0, 0, 0 } // bufferInfo + }; + return resultInfo; +}; + +vk::VkDescriptorInfo createDescriptorInfo (vk::VkImageView imageView, vk::VkImageLayout layout) +{ + const vk::VkDescriptorInfo resultInfo = + { + 0, // bufferView + 0, // sampler + imageView, // imageView + layout, // imageLayout + { (vk::VkBuffer)0, 0, 0 } // bufferInfo + }; + return resultInfo; +}; + +vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler, vk::VkImageView imageView, vk::VkImageLayout layout) +{ + const vk::VkDescriptorInfo resultInfo = + { + 0, // bufferView + sampler, // sampler + imageView, // imageView + layout, // imageLayout + { (vk::VkBuffer)0, 0, 0 } // bufferInfo + }; + return resultInfo; +}; + +vk::Move createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr* outAllocation, vkt::Context& context) +{ + const vk::DeviceInterface& m_vki = context.getDeviceInterface(); + const vk::VkDevice m_device = context.getDevice(); + vk::Allocator& m_allocator = context.getDefaultAllocator(); + + DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize); + + const vk::VkBufferUsageFlags usageFlags = (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) ; + const vk::VkBufferCreateInfo createInfo = + { + vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + DE_NULL, + (vk::VkDeviceSize)bufferSize, // size + usageFlags, // usage + 0u, // flags + vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode + 0u, // queueFamilyCount + DE_NULL, // pQueueFamilyIndices + }; + vk::Move buffer (vk::createBuffer(m_vki, m_device, &createInfo)); + de::MovePtr allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible)); + void* mapPtr = allocation->getHostPtr(); + + if (offset) + deMemset(mapPtr, 0x5A, (size_t)offset); + deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4)); + deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4)); + deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4)); + + flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize); + + *outAllocation = allocation; + return buffer; +} + +vk::Move createDescriptorSetLayout (vkt::Context& context) +{ + + const vk::DeviceInterface& m_vki = context.getDeviceInterface(); + const vk::VkDevice m_device = context.getDevice(); + + vk::DescriptorSetLayoutBuilder builder; + + builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT); + + builder.addSingleBinding( vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT); + + + return builder.build(m_vki, m_device); +} + +vk::Move createDescriptorPool (vkt::Context& context) +{ + const vk::DeviceInterface& m_vki = context.getDeviceInterface(); + const vk::VkDevice m_device = context.getDevice(); + + return vk::DescriptorPoolBuilder() + .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .addType( vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u) + .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1); +} + +vk::Move createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, vkt::Context& context) +{ + const vk::DeviceInterface& m_vki = context.getDeviceInterface(); + const vk::VkDevice m_device = context.getDevice(); + + const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE); + const vk::VkDescriptorInfo bufferInfos[2] = + { + createDescriptorInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])), + createDescriptorInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])), + }; + + vk::Move descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout); + vk::DescriptorSetUpdateBuilder builder; + + // result + builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo); + + // buffers + builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfos[0]); + + builder.update(m_vki, m_device); + return descriptorSet; +} diff --git a/external/vulkancts/modules/vulkan/api/BufferComputeInstance.hpp b/external/vulkancts/modules/vulkan/api/BufferComputeInstance.hpp new file mode 100644 index 0000000..b95392b --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/BufferComputeInstance.hpp @@ -0,0 +1,75 @@ +#ifndef BUFFERCOMPUTEINSTANCE_HPP +#define BUFFERCOMPUTEINSTANCE_HPP + + +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + + + +#include "vktTestCase.hpp" + +#include "vkDefs.hpp" +#include "vkRef.hpp" +#include "vkRefUtil.hpp" +#include "vkPlatform.hpp" +#include "vkPrograms.hpp" +#include "vkMemUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkQueryUtil.hpp" + +#include "tcuVector.hpp" +#include "tcuVectorUtil.hpp" +#include "tcuTexture.hpp" +#include "tcuTextureUtil.hpp" +#include "tcuResultCollector.hpp" +#include "tcuTestLog.hpp" +#include "tcuRGBA.hpp" +#include "tcuSurface.hpp" +#include "tcuImageCompare.hpp" + +#include "deUniquePtr.hpp" +#include "deSharedPtr.hpp" +#include "deStringUtil.hpp" +#include "deArrayUtil.hpp" + +#include "tcuDefs.hpp" +#include "tcuTestCase.hpp" +#include "ComputeInstanceResultBuffer.hpp" + +vk::Move createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr* outAllocation, vkt::Context& context); +vk::Move createBufferView (vk::VkBuffer buffer, deUint32 offset) ; +vk::Move createDescriptorSetLayout (vkt::Context& context) ; +vk::Move createDescriptorPool (vkt::Context& context) ; +vk::Move createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, vkt::Context& context) ; + +#endif //VULKANCTS_BUFFERCOMPUTEINSTANCE_HPP diff --git a/external/vulkancts/modules/vulkan/api/CMakeLists.txt b/external/vulkancts/modules/vulkan/api/CMakeLists.txt index fc48238..9edb91a 100644 --- a/external/vulkancts/modules/vulkan/api/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/api/CMakeLists.txt @@ -19,6 +19,12 @@ set(DEQP_VK_API_SRCS vktApiBufferViewAccessTests.hpp vktApiFeatureInfo.cpp vktApiFeatureInfo.hpp + vktApiCommandBuffersTests.cpp + vktApiCommandBuffersTests.hpp + ComputeInstanceResultBuffer.cpp + ComputeInstanceResultBuffer.hpp + BufferComputeInstance.cpp + BufferComputeInstance.hpp ) set(DEQP_VK_API_LIBS diff --git a/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.cpp b/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.cpp new file mode 100644 index 0000000..b03d686 --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.cpp @@ -0,0 +1,116 @@ + +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + + + +#include "ComputeInstanceResultBuffer.hpp" + + +using namespace vk; +using tcu::TestLog; +using de::UniquePtr; + + +ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki, + vk::VkDevice device, + vk::Allocator& allocator) + : m_vki (vki) + , m_device (device) + , m_bufferMem (DE_NULL) + , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem)) + , m_bufferBarrier (createResultBufferBarrier(*m_buffer)) +{ +} + +void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const +{ + invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results)); + deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results)); +} + +de::MovePtr allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement) +{ + const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer); + de::MovePtr allocation = allocator.allocate(requirements, requirement); + + VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset())); + return allocation; +} + + +vk::Move ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki, + vk::VkDevice device, + vk::Allocator& allocator, + de::MovePtr* outAllocation) +{ + const vk::VkBufferCreateInfo createInfo = + { + vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + DE_NULL, + (vk::VkDeviceSize)DATA_SIZE, // size + vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage + 0u, // flags + vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode + 0u, // queueFamilyCount + DE_NULL, // pQueueFamilyIndices + }; + vk::Move buffer (vk::createBuffer(vki, device, &createInfo)); + de::MovePtr allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible)); + const float clearValue = -1.0f; + void* mapPtr = allocation->getHostPtr(); + + for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float)) + deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float)); + + flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE); + + *outAllocation = allocation; + return buffer; +} + +vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer) +{ + const vk::VkBufferMemoryBarrier bufferBarrier = + { + vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + DE_NULL, + vk::VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, // outputMask + vk::VK_MEMORY_INPUT_HOST_READ_BIT, // inputMask + vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex + vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex + buffer, // buffer + (vk::VkDeviceSize)0u, // offset + DATA_SIZE, // size + }; + return bufferBarrier; +} diff --git a/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.hpp b/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.hpp new file mode 100644 index 0000000..170131d --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/ComputeInstanceResultBuffer.hpp @@ -0,0 +1,102 @@ +#ifndef _COMPUTEINSTANCERESULTBUFFER_HPP +#define _COMPUTEINSTANCERESULTBUFFER_HPP + + +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + + + +#include "vktTestCase.hpp" + +#include "vkDefs.hpp" +#include "vkRef.hpp" +#include "vkRefUtil.hpp" +#include "vkPlatform.hpp" +#include "vkPrograms.hpp" +#include "vkMemUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkQueryUtil.hpp" + +#include "tcuVector.hpp" +#include "tcuVectorUtil.hpp" +#include "tcuTexture.hpp" +#include "tcuTextureUtil.hpp" +#include "tcuResultCollector.hpp" +#include "tcuTestLog.hpp" +#include "tcuRGBA.hpp" +#include "tcuSurface.hpp" +#include "tcuImageCompare.hpp" + +#include "deUniquePtr.hpp" +#include "deSharedPtr.hpp" +#include "deStringUtil.hpp" +#include "deArrayUtil.hpp" + + + +class ComputeInstanceResultBuffer +{ +public: + enum + { + DATA_SIZE = sizeof(tcu::Vec4[4]) + }; + + ComputeInstanceResultBuffer (const vk::DeviceInterface& vki, + vk::VkDevice device, + vk::Allocator& allocator); + + void readResultContentsTo (tcu::Vec4 (*results)[4]) const; + + inline vk::VkBuffer getBuffer (void) const { return *m_buffer; } + inline const void* getResultReadBarrier (void) const { return &m_bufferBarrier; } + +private: + static vk::Move createResultBuffer (const vk::DeviceInterface& vki, + vk::VkDevice device, + vk::Allocator& allocator, + de::MovePtr* outAllocation); + + static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer); + + const vk::DeviceInterface& m_vki; + const vk::VkDevice m_device; + + de::MovePtr m_bufferMem; + const vk::Unique m_buffer; + const vk::VkBufferMemoryBarrier m_bufferBarrier; +}; + +de::MovePtr allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement); + +#endif //VULKANCTS_COMPUTEINSTANCERESULTBUFFER_HPP diff --git a/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp new file mode 100644 index 0000000..07af38d --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp @@ -0,0 +1,863 @@ +#include "vktApiCommandBuffersTests.hpp" +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + +#include "vktApiTests.hpp" +#include +#include + +#include "vktTestCaseUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkDefs.hpp" +#include "vkPlatform.hpp" +#include "vkStrUtil.hpp" +#include "vkRef.hpp" +#include "vkRefUtil.hpp" +#include "vkQueryUtil.hpp" +#include "vkMemUtil.hpp" +#include "vkDeviceUtil.hpp" +#include "vkPrograms.hpp" +#include "vkTypeUtil.hpp" +#include "vkPlatform.hpp" +#include "tcuTestLog.hpp" +#include "tcuFormatUtil.hpp" +#include "deUniquePtr.hpp" + +#include "BufferComputeInstance.hpp" +#include "ComputeInstanceResultBuffer.hpp" + +namespace vkt +{ +namespace api +{ +namespace +{ + + +using namespace vk; +using tcu::TestLog; +using de::UniquePtr; + +const deUint64 INFINITE_TIMEOUT = ~(deUint64)0u; + +tcu::TestStatus createBufferTest (Context& context) +{ + const VkDevice vkDevice = context.getDevice(); + const DeviceInterface& vk = context.getDeviceInterface(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + + const VkCmdPoolCreateInfo cmdPoolParams = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + queueFamilyIndex, // deUint32 queueFamilyIndex; + VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT // VkCmdPoolCreateFlags flags; + }; + const Unique cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); + + // Command buffer + const VkCmdBufferCreateInfo cmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + const Unique cmdBuf (createCommandBuffer(vk, vkDevice, &cmdBufParams)); + + return tcu::TestStatus::pass("create Command Buffer succeeded"); +} + + +tcu::TestStatus executeSecondaryBufferTest (Context& context) +{ + + const VkDevice vkDevice = context.getDevice(); + const DeviceInterface& vk = context.getDeviceInterface(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + + const VkCmdPoolCreateInfo cmdPoolParams = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + queueFamilyIndex, // deUint32 queueFamilyIndex; + VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT // VkCmdPoolCreateFlags flags; + }; + const Unique cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); + + // Command buffer + const VkCmdBufferCreateInfo cmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + const Unique primCmdBuf (createCommandBuffer(vk, vkDevice, &cmdBufParams)); + + // Secondary Command buffer + const VkCmdBufferCreateInfo secCmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_SECONDARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + const Unique secCmdBuf (createCommandBuffer(vk, vkDevice, &secCmdBufParams)); + + const VkCmdBufferBeginInfo primCmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + 0,//VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags + (VkRenderPass)0u, // renderPass + 0u, // subpass + (VkFramebuffer)0u, // framebuffer + }; + + const VkCmdBufferBeginInfo secCmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + 0u, //VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags + (VkRenderPass)0u, // renderPass + 0u, // subpass + (VkFramebuffer)0u, // framebuffer + }; + + + // Fill create info struct for event + const VkEventCreateInfo eventCreateInfo = + { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, + DE_NULL, + 0u, + }; + + // create event that will be used to check if secondary command buffer has been executed + const Unique event ( createEvent(vk, vkDevice, &eventCreateInfo ) ); + + // reset event + vk.resetEvent(vkDevice, *event); + + // record primary command buffer + vk.beginCommandBuffer( *primCmdBuf, &primCmdBufBeginInfo); + { + // record secondary command buffer + vk.beginCommandBuffer( *secCmdBuf, &secCmdBufBeginInfo); + { + // allow execution of event during every stage of pipeline + VkPipelineStageFlags stageMask = 0x0000FFFF; + + // record setting event + vk.cmdSetEvent(*secCmdBuf, *event,stageMask); + } + + // end recording of secondary buffers + vk.endCommandBuffer( *secCmdBuf ); + + // execute secondary buffer + vk.cmdExecuteCommands( *primCmdBuf, 1, &secCmdBuf.get()); + } + vk.endCommandBuffer( *primCmdBuf ); + + + vk.resetCommandBuffer(*primCmdBuf, 0u); + + const VkFenceCreateInfo fenceCreateInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + DE_NULL, + 0u, // flags + }; + + // create fence to wait for execution of queue + const Unique fence (createFence(vk, vkDevice, &fenceCreateInfo)); + + // submit primary buffer, the secondary should be executed too + vk.queueSubmit(queue,1, &primCmdBuf.get(), *fence); + + // wait for end of execution of queue + const deUint64 infiniteTimeout = ~(deUint64)0u; + vk.waitForFences(vkDevice, 1, &fence.get(), 0u, infiniteTimeout); + + // check if secondary buffer has been executed + VkResult result = vk.getEventStatus(vkDevice,*event); + if (result == VK_EVENT_SET) return tcu::TestStatus::pass("Execute Secondary Command Buffer succeeded"); + else return tcu::TestStatus::pass("Execute Secondary Command Buffer FAILED"); + + +} + +tcu::TestStatus executeOrderTest (Context& context) +{ + const DeviceInterface& m_vki = context.getDeviceInterface(); + const VkDevice m_device = context.getDevice(); + const VkQueue m_queue = context.getUniversalQueue(); + const deUint32 m_queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + Allocator& m_allocator = context.getDefaultAllocator(); + const ComputeInstanceResultBuffer m_result(m_vki, m_device, m_allocator); + + enum + { + ADDRESSABLE_SIZE = 256, // allocate a lot more than required + }; + + const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); + const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f); + + const deUint32 dataOffsetA = (0u); + const deUint32 dataOffsetB = (0u); + const deUint32 viewOffsetA = (0u); + const deUint32 viewOffsetB = (0u); + const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE; + const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE; + + de::MovePtr bufferMemA; + const Unique bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA, context)); + + de::MovePtr bufferMemB; + const Unique bufferB ((Move())); + + const Unique descriptorSetLayout (createDescriptorSetLayout(context)); + const Unique descriptorPool (createDescriptorPool(context)); + + const Unique descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer(), context)); + const VkDescriptorSet descriptorSets[] = { *descriptorSet }; + const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets); + + const VkPipelineLayoutCreateInfo layoutCreateInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + DE_NULL, + numDescriptorSets, // descriptorSetCount + &descriptorSetLayout.get(), // pSetLayouts + 0u, // pushConstantRangeCount + DE_NULL, // pPushConstantRanges + }; + Unique m_pipelineLayout (createPipelineLayout(m_vki, m_device, &layoutCreateInfo)); + + + const Unique computeModuleGood (createShaderModule(m_vki, m_device, context.getBinaryCollection().get("compute_good"), (VkShaderModuleCreateFlags)0u)); + const Unique computeModuleBad (createShaderModule(m_vki, m_device, context.getBinaryCollection().get("compute_bad"), (VkShaderModuleCreateFlags)0u)); + + const VkShaderCreateInfo shaderCreateInfoGood = + { + VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, + DE_NULL, + *computeModuleGood, // module + "main", // pName + 0u, // flags + VK_SHADER_STAGE_COMPUTE + }; + const VkShaderCreateInfo shaderCreateInfoBad = + { + VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, + DE_NULL, + *computeModuleBad, // module + "main", // pName + 0u, // flags + VK_SHADER_STAGE_COMPUTE + }; + + const Unique computeShaderGood (createShader(m_vki, m_device, &shaderCreateInfoGood)); + const Unique computeShaderBad (createShader(m_vki, m_device, &shaderCreateInfoBad)); + + const VkPipelineShaderStageCreateInfo csGood = + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + DE_NULL, + VK_SHADER_STAGE_COMPUTE, // stage + *computeShaderGood, // shader + DE_NULL, // pSpecializationInfo + }; + + const VkPipelineShaderStageCreateInfo csBad = + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + DE_NULL, + VK_SHADER_STAGE_COMPUTE, // stage + *computeShaderBad, // shader + DE_NULL, // pSpecializationInfo + }; + + + const VkComputePipelineCreateInfo createInfoGood = + { + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + DE_NULL, + csGood, // cs + 0u, // flags + *m_pipelineLayout, // descriptorSetLayout.get() + (VkPipeline)0, // basePipelineHandle + 0u, // basePipelineIndex + }; + + const VkComputePipelineCreateInfo createInfoBad = + { + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + DE_NULL, + csBad, // cs + 0u, // flags + *m_pipelineLayout, // descriptorSetLayout.get() + (VkPipeline)0, // basePipelineHandle + 0u, // basePipelineIndex + }; + + const Unique m_pipelineGood (createComputePipeline(m_vki, m_device, (VkPipelineCache)0u, &createInfoGood) ); + const Unique m_pipelineBad (createComputePipeline(m_vki, m_device, (VkPipelineCache)0u, &createInfoBad) ); + + const VkMemoryInputFlags inputBit = (VK_MEMORY_INPUT_UNIFORM_READ_BIT) ; + const VkBufferMemoryBarrier bufferBarrierA = + { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + DE_NULL, + VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask + inputBit, // inputMask + VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex + VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex + *bufferA, // buffer + (VkDeviceSize)0u, // offset + (VkDeviceSize)bufferSizeA, // size + }; + + const VkBufferMemoryBarrier bufferBarrierB = + { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + DE_NULL, + VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask + inputBit, // inputMask + VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex + VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex + *bufferB, // buffer + (VkDeviceSize)0u, // offset + (VkDeviceSize)bufferSizeB, // size + }; + + const deUint32 numSrcBuffers = 1u; + + + const deUint32* const dynamicOffsets = (DE_NULL); + const deUint32 numDynamicOffsets = (0); + const void* const preBarriers[] = { &bufferBarrierA, &bufferBarrierB }; + const int numPreBarriers = numSrcBuffers; + const void* const postBarriers[] = { m_result.getResultReadBarrier() }; + const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers); + const tcu::Vec4 refQuadrantValue14 = (colorA2); + const tcu::Vec4 refQuadrantValue23 = (colorA1); + const tcu::Vec4 references[4] = + { + refQuadrantValue14, + refQuadrantValue23, + refQuadrantValue23, + refQuadrantValue14, + }; + tcu::Vec4 results[4]; + + // submit and wait begin + + const tcu::UVec3 m_numWorkGroups = tcu::UVec3(4, 1, 1); + const VkCmdPoolCreateInfo cmdPoolCreateInfo = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, + DE_NULL, + m_queueFamilyIndex, // m_queueFamilyIndex + VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags + }; + const Unique cmdPool (createCommandPool(m_vki, m_device, &cmdPoolCreateInfo)); + + const VkFenceCreateInfo fenceCreateInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + DE_NULL, + 0u, // flags + }; + + const VkCmdBufferCreateInfo cmdBufCreateInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, + DE_NULL, + *cmdPool, // cmdPool + VK_CMD_BUFFER_LEVEL_PRIMARY, // level + 0u, // flags + }; + const VkCmdBufferBeginInfo cmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags + (VkRenderPass)0u, // renderPass + 0u, // subpass + (VkFramebuffer)0u, // framebuffer + }; + + const Unique cmdCompleteFence (createFence(m_vki, m_device, &fenceCreateInfo)); + const Unique cmd (createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo)); + const deUint64 infiniteTimeout = ~(deUint64)0u; + + VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo)); + + m_vki.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineBad); + m_vki.cmdBindPipeline(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineGood); + m_vki.cmdBindDescriptorSets(*cmd, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, numDescriptorSets, descriptorSets, numDynamicOffsets, dynamicOffsets); + + if (numPreBarriers) + m_vki.cmdPipelineBarrier(*cmd, 0u, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_FALSE, numPreBarriers, preBarriers); + + m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z()); + m_vki.cmdPipelineBarrier(*cmd, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, numPostBarriers, postBarriers); + VK_CHECK(m_vki.endCommandBuffer(*cmd)); + + // run + VK_CHECK(m_vki.queueSubmit(m_queue, 1, &cmd.get(), *cmdCompleteFence)); + VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure + + // submit and wait end + m_result.readResultContentsTo(&results); + + // verify + if (results[0] == references[0] && + results[1] == references[1] && + results[2] == references[2] && + results[3] == references[3]) + { + return tcu::TestStatus::pass("Pass"); + } + else if (results[0] == tcu::Vec4(-1.0f) && + results[1] == tcu::Vec4(-1.0f) && + results[2] == tcu::Vec4(-1.0f) && + results[3] == tcu::Vec4(-1.0f)) + { + context.getTestContext().getLog() + << tcu::TestLog::Message + << "Result buffer was not written to." + << tcu::TestLog::EndMessage; + return tcu::TestStatus::fail("Result buffer was not written to"); + } + else + { + context.getTestContext().getLog() + << tcu::TestLog::Message + << "Error expected [" + << references[0] << ", " + << references[1] << ", " + << references[2] << ", " + << references[3] << "], got [" + << results[0] << ", " + << results[1] << ", " + << results[2] << ", " + << results[3] << "]" + << tcu::TestLog::EndMessage; + return tcu::TestStatus::fail("Invalid result values"); + } +}; + +tcu::TestStatus explicitResetCmdBufferTest(Context& context) +{ + const VkDevice vkDevice = context.getDevice(); + const DeviceInterface& vk = context.getDeviceInterface(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + + const VkCmdPoolCreateInfo cmdPoolParams = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + queueFamilyIndex, // deUint32 queueFamilyIndex; + VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT // VkCmdPoolCreateFlags flags; + }; + const Unique cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); + + // Command buffer + const VkCmdBufferCreateInfo cmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + const Unique cmdBuf (createCommandBuffer(vk, vkDevice, &cmdBufParams)); + + const VkCmdBufferBeginInfo cmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + DE_NULL, + 0u, + DE_NULL, + }; + + const VkEventCreateInfo eventCreateInfo = + { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkEventCreateFlags flags; + }; + const Unique event (createEvent(vk, vkDevice, &eventCreateInfo)); + + // Put the command buffer in recording state. + VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo)); + { + vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS); + } + VK_CHECK(vk.endCommandBuffer(*cmdBuf)); + + // We'll use a fence to wait for the execution of the queue + const VkFenceCreateInfo fenceCreateInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkFenceCreateFlags flags + }; + const Unique fence (createFence(vk, vkDevice, &fenceCreateInfo)); + + // Submitting the command buffer that sets the event to the queue + VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuf.get(), *fence)); + + // Waiting for the queue to finish executing + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); + + // 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_CHECK(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. + VK_CHECK(vk.resetCommandBuffer(*cmdBuf, 0)); + // Reset the fence so that we can reuse it + VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); + + // Submit the command buffer after resetting. It should have no commands + // recorded, so the event should remain unsignaled. + VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuf.get(), *fence)); + // Waiting for the queue to finish executing + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); + + // Check if the event remained unset. + if(vk.getEventStatus(vkDevice,*event) == VK_EVENT_RESET) + return tcu::TestStatus::pass("Buffer was reset properly."); + else + return tcu::TestStatus::fail("Buffer was not reset properly."); +} + +tcu::TestStatus implicitResetCmdBufferTest(Context& context) +{ + const VkDevice vkDevice = context.getDevice(); + const DeviceInterface& vk = context.getDeviceInterface(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + + const VkCmdPoolCreateInfo cmdPoolParams = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + queueFamilyIndex, // deUint32 queueFamilyIndex; + VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT // VkCmdPoolCreateFlags flags; + }; + const Unique cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); + + // Command buffer + const VkCmdBufferCreateInfo cmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + const Unique cmdBuf (createCommandBuffer(vk, vkDevice, &cmdBufParams)); + + const VkCmdBufferBeginInfo cmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + DE_NULL, + 0u, + DE_NULL, + }; + + const VkEventCreateInfo eventCreateInfo = + { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkEventCreateFlags flags; + }; + const Unique event (createEvent(vk, vkDevice, &eventCreateInfo)); + + // Put the command buffer in recording state. + VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo)); + { + // Set the event + vk.cmdSetEvent(*cmdBuf, *event, VK_PIPELINE_STAGE_ALL_GPU_COMMANDS); + } + VK_CHECK(vk.endCommandBuffer(*cmdBuf)); + + // We'll use a fence to wait for the execution of the queue + const VkFenceCreateInfo fenceCreateInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkFenceCreateFlags flags + }; + const Unique fence (createFence(vk, vkDevice, &fenceCreateInfo)); + + // Submitting the command buffer that sets the event to the queue + VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuf.get(), *fence)); + + // Waiting for the queue to finish executing + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); + + // Check if the buffer was executed + if (vk.getEventStatus(vkDevice, *event) != VK_EVENT_SET) + return tcu::TestStatus::fail("Failed to set the event."); + + // Reset the event + vk.resetEvent(vkDevice, *event); + if(vk.getEventStatus(vkDevice, *event) != VK_EVENT_RESET) + return tcu::TestStatus::fail("Failed to reset the event."); + + // Reset the command buffer by putting it in recording state again. This + // should empty the command buffer. + VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginInfo)); + VK_CHECK(vk.endCommandBuffer(*cmdBuf)); + // Reset the fence so that we can reuse it + VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); + + // Submit the command buffer after resetting. It should have no commands + // recorded, so the event should remain unsignaled. + VK_CHECK(vk.queueSubmit(queue, 1, &cmdBuf.get(), *fence)); + // Waiting for the queue to finish executing + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), 0u, INFINITE_TIMEOUT)); + + // Check if the event remained unset. + if(vk.getEventStatus(vkDevice, *event) == VK_EVENT_RESET) + return tcu::TestStatus::pass("Buffer was reset properly."); + else + return tcu::TestStatus::fail("Buffer was not reset properly."); +} + +tcu::TestStatus bulkResetCmdBufferTest(Context& context) +{ + const VkDevice vkDevice = context.getDevice(); + const DeviceInterface& vk = context.getDeviceInterface(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + + const short BUFFER_COUNT = 2; + + const VkCmdPoolCreateInfo cmdPoolParams = + { + VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + queueFamilyIndex, // deUint32 queueFamilyIndex; + 0u, // VkCmdPoolCreateFlags flags; + }; + const Unique cmdPool (createCommandPool(vk, vkDevice, &cmdPoolParams)); + + // Command buffer + const VkCmdBufferCreateInfo cmdBufParams = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *cmdPool, // VkCmdPool pool; + VK_CMD_BUFFER_LEVEL_PRIMARY, // VkCmdBufferLevel level; + 0u, // VkCmdBufferCreateFlags flags; + }; + VkCmdBuffer cmdBuffers[BUFFER_COUNT]; + for (short i = 0; i < BUFFER_COUNT; ++i) + VK_CHECK(vk.createCommandBuffer(vkDevice, &cmdBufParams, &cmdBuffers[i])); + + const VkCmdBufferBeginInfo cmdBufBeginInfo = + { + VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, + DE_NULL, + VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, + DE_NULL, + 0u, + DE_NULL, + }; + + const VkEventCreateInfo eventCreateInfo = + { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkEventCreateFlags flags; + }; + VkEvent events[BUFFER_COUNT]; + for (short i = 0; i < BUFFER_COUNT; ++i) + VK_CHECK(vk.createEvent(vkDevice, &eventCreateInfo, &events[i])); + + // Record the command buffers + for (short i = 0; i < BUFFER_COUNT; ++i) + { + VK_CHECK(vk.beginCommandBuffer(cmdBuffers[i], &cmdBufBeginInfo)); + { + vk.cmdSetEvent(cmdBuffers[i], events[i], VK_PIPELINE_STAGE_ALL_GPU_COMMANDS); + } + VK_CHECK(vk.endCommandBuffer(cmdBuffers[i])); + } + + // We'll use a fence to wait for the execution of the queue + const VkFenceCreateInfo fenceCreateInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkFenceCreateFlags flags + }; + const Unique fence (createFence(vk, vkDevice, &fenceCreateInfo)); + + // Submit the alpha command buffer to the queue + VK_CHECK(vk.queueSubmit(queue, BUFFER_COUNT, cmdBuffers, *fence)); + // Wait for the queue + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, INFINITE_TIMEOUT)); + // Reset the fence so that we can use it again + VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); + + // Check if the buffers were executed + for (short i = 0; i < BUFFER_COUNT; ++i) + if (vk.getEventStatus(vkDevice, events[i]) != VK_EVENT_SET) + return tcu::TestStatus::fail("Failed to set the event."); + + // Reset the events + for (short i = 0; i < BUFFER_COUNT; ++i) + { + VK_CHECK(vk.resetEvent(vkDevice, events[i])); + // Check if the event was reset properly + if (vk.getEventStatus(vkDevice, events[0]) != VK_EVENT_RESET) + return tcu::TestStatus::fail("Failed to reset the event."); + } + + // Reset the command buffers by resetting the command pool + VK_CHECK(vk.resetCommandPool(vkDevice, *cmdPool, 0u)); + + // Submit the command buffers to the queue + VK_CHECK(vk.queueSubmit(queue, BUFFER_COUNT, cmdBuffers, *fence)); + // Wait for the queue + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, INFINITE_TIMEOUT)); + + // Check if the event remained unset. + for (short i = 0; i < BUFFER_COUNT; ++i) + if (vk.getEventStatus(vkDevice, events[i]) != VK_EVENT_RESET) + return tcu::TestStatus::fail("Buffers were not reset properly."); + + return tcu::TestStatus::pass("All buffers were reset properly."); +} + +} // anonymous + + void genComputeSource (SourceCollections& programCollection) + { + const char* const versionDecl = glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES); + std::ostringstream buf_good; + + buf_good << versionDecl << "\n" + << "" + << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + << "layout(set = 0, binding = 1, std140) uniform BufferName\n" + << "{\n" + << " highp vec4 colorA;\n" + << " highp vec4 colorB;\n" + << "} b_instance;\n" + << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n" + << "{\n" + << " highp vec4 read_colors[4];\n" + << "} b_out;\n" + << "void main(void)\n" + << "{\n" + << " highp int quadrant_id = int(gl_WorkGroupID.x);\n" + << " highp vec4 result_color;\n" + << " if (quadrant_id == 1 || quadrant_id == 2)\n" + << " result_color = b_instance.colorA;\n" + << " else\n" + << " result_color = b_instance.colorB;\n" + << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n" + << "}\n"; + + programCollection.glslSources.add("compute_good") << glu::ComputeSource(buf_good.str()); + + + std::ostringstream buf_bad; + + buf_bad << versionDecl << "\n" + << "" + << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + << "layout(set = 0, binding = 1, std140) uniform BufferName\n" + << "{\n" + << " highp vec4 colorA;\n" + << " highp vec4 colorB;\n" + << "} b_instance;\n" + << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n" + << "{\n" + << " highp vec4 read_colors[4];\n" + << "} b_out;\n" + << "void main(void)\n" + << "{\n" + << " highp int quadrant_id = int(gl_WorkGroupID.x);\n" + << " highp vec4 result_color;\n" + << " if (quadrant_id == 1 || quadrant_id == 2)\n" + << " result_color = b_instance.colorA;\n" + << " else\n" + << " result_color = b_instance.colorB;\n" + << " b_out.read_colors[gl_WorkGroupID.x] = vec4(0.0, 0.0, 0.0, 0.0);\n" + << "}\n"; + + programCollection.glslSources.add("compute_bad") << glu::ComputeSource(buf_bad.str()); + } + + +tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx) +{ + de::MovePtr commandBuffersTests (new tcu::TestCaseGroup(testCtx, "command_buffers", "Command Buffers Tests")); + + addFunctionCase (commandBuffersTests.get(), "create_buffers", "", createBufferTest); + addFunctionCase (commandBuffersTests.get(), "execute_secondary_buffers", "", executeSecondaryBufferTest); + addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_of_execution", "", genComputeSource, executeOrderTest ); + addFunctionCase (commandBuffersTests.get(), "explicit_reset", "", explicitResetCmdBufferTest); + addFunctionCase (commandBuffersTests.get(), "implicit_reset", "", implicitResetCmdBufferTest); + addFunctionCase (commandBuffersTests.get(), "bulk_reset", "", bulkResetCmdBufferTest); + + return commandBuffersTests.release(); +} + +} // api +} // vkt diff --git a/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.hpp b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.hpp new file mode 100644 index 0000000..89499ba --- /dev/null +++ b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.hpp @@ -0,0 +1,51 @@ + +#ifndef _VKTAPICOMMANDBUFFERSTESTS_HPP +#define _VKTAPICOMMANDBUFFERSTESTS_HPP + +/*------------------------------------------------------------------------- + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2015 The Khronos Group Inc. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Materials. + * + * The Materials are Confidential Information as defined by the + * Khronos Membership Agreement until designated non-confidential by + * Khronos, at which point this condition clause shall be removed. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + * + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestCase.hpp" + +namespace vkt +{ +namespace api +{ + +tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx); + +} // api +} // vkt + + +#endif /* VKTAPICOMMANDBUFFERSTESTS_HPP_ */ diff --git a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp index b751dd6..004c19c 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiTests.cpp @@ -43,6 +43,7 @@ #include "vktApiBufferViewCreateTests.hpp" #include "vktApiBufferViewAccessTests.hpp" #include "vktApiFeatureInfo.hpp" +#include "vktApiCommandBuffersTests.hpp" namespace vkt { @@ -74,7 +75,7 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) apiTests->addChild(createObjectManagementTests (testCtx)); apiTests->addChild(createBufferTests (testCtx)); apiTests->addChild(createBufferViewTests (testCtx)); - + apiTests->addChild(createCommandBuffersTests (testCtx)); return apiTests.release(); } diff --git a/framework/platform/android/tcuAndroidPlatform.cpp b/framework/platform/android/tcuAndroidPlatform.cpp index d9a46d5..10a242b 100644 --- a/framework/platform/android/tcuAndroidPlatform.cpp +++ b/framework/platform/android/tcuAndroidPlatform.cpp @@ -190,7 +190,7 @@ class VulkanLibrary : public vk::Library { public: VulkanLibrary (void) - : m_library ("libvulkan.so") +: m_library    ("libVK_IMG.so") , m_driver (m_library) { } diff --git a/targets/android/android.cmake b/targets/android/android.cmake index 59d5e9c..1cbb299 100644 --- a/targets/android/android.cmake +++ b/targets/android/android.cmake @@ -21,8 +21,8 @@ if (DEQP_SUPPORT_EGL) endif () # Platform libs -find_library(LOG_LIBRARY NAMES log PATHS /usr/lib) -set(DEQP_PLATFORM_LIBRARIES ${DEQP_PLATFORM_LIBRARIES} ${LOG_LIBRARY}) +# +# if (DE_ANDROID_API GREATER 8) # libandroid for NativeActivity APIs -- 2.7.4