diff options
author | Piotr Byszewski <piotr.byszewski@mobica.com> | 2023-01-27 09:48:28 +0100 |
---|---|---|
committer | Piotr Byszewski <piotr.byszewski@mobica.com> | 2023-01-27 09:48:36 +0100 |
commit | e78430810211a7ab29cc55fa073057a6c8dccaf3 (patch) | |
tree | b5e62908335996c2f53dda60b08db9596311acf0 | |
parent | 74d9023c71c0905da3d701cd4cfbd390e7bbf4fd (diff) | |
parent | a7da9993440d3a7b87040e3bf28934ddc6950743 (diff) | |
download | VK-GL-CTS-e78430810211a7ab29cc55fa073057a6c8dccaf3.tar.gz VK-GL-CTS-e78430810211a7ab29cc55fa073057a6c8dccaf3.tar.bz2 VK-GL-CTS-e78430810211a7ab29cc55fa073057a6c8dccaf3.zip |
Merge vk-gl-cts/vulkan-cts-1.2.8 into vk-gl-cts/vulkan-cts-1.3.0
Change-Id: I29ea16db0e7ddc2b374888f41ed07523b233aedb
7 files changed, 534 insertions, 210 deletions
diff --git a/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp index 067cc697a..905533469 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiCommandBuffersTests.cpp @@ -3413,8 +3413,8 @@ tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context) // record secondary command buffer VK_CHECK(vk.beginCommandBuffer(cmdBuffers[ndx], &secCmdBufBeginInfo)); { - // wait for event - vk.cmdWaitEvents(cmdBuffers[ndx], 1, &eventOne.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, DE_NULL, 0u, DE_NULL, 0u, DE_NULL); + // set event + vk.cmdSetEvent(cmdBuffers[ndx], *eventOne, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); } // end recording of secondary buffers endCommandBuffer(vk, cmdBuffers[ndx]); @@ -3440,54 +3440,69 @@ tcu::TestStatus executeSecondaryBufferTwiceTest(Context& context) const Unique<VkFence> fenceOne (createFence(vk, vkDevice)); const Unique<VkFence> fenceTwo (createFence(vk, vkDevice)); - const VkSubmitInfo submitInfoOne = + const uint64_t semaphoreWaitValue = 1ull; + const VkPipelineStageFlags semaphoreWaitStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + const auto semaphore = createSemaphoreType(vk, vkDevice, VK_SEMAPHORE_TYPE_TIMELINE); + + // Use timeline semaphore to wait for signal from the host. + const VkTimelineSemaphoreSubmitInfo timelineWaitSubmitInfo = { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType - DE_NULL, // pNext - 0u, // waitSemaphoreCount - DE_NULL, // pWaitSemaphores - (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask - 1, // commandBufferCount - &primCmdBufOne.get(), // pCommandBuffers - 0u, // signalSemaphoreCount - DE_NULL, // pSignalSemaphores + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, // VkStructureType sType; + nullptr, // const void* pNext; + 1u, // uint32_t waitSemaphoreValueCount; + &semaphoreWaitValue, // const uint64_t* pWaitSemaphoreValues; + 0u, // uint32_t signalSemaphoreValueCount; + nullptr, // const uint64_t* pSignalSemaphoreValues; }; - // submit primary buffer, the secondary should be executed too - VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoOne, *fenceOne)); - - // wait for buffer to stop at event for 100 microseconds - vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000); + const VkSubmitInfo submitInfo = + { + VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; + &timelineWaitSubmitInfo, // const void* pNext; + 1u, // uint32_t waitSemaphoreCount; + &semaphore.get(), // const VkSemaphore* pWaitSemaphores; + &semaphoreWaitStage, // const VkPipelineStageFlags* pWaitDstStageMask; + 1u, // uint32_t commandBufferCount; + &primCmdBufOne.get(), // const VkCommandBuffer* pCommandBuffers; + 0u, // uint32_t signalSemaphoreCount; + nullptr, // const VkSemaphore* pSignalSemaphores; + }; + VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fenceOne)); - const VkSubmitInfo submitInfoTwo = + const VkSubmitInfo submitInfo2 = { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType - DE_NULL, // pNext - 0u, // waitSemaphoreCount - DE_NULL, // pWaitSemaphores - (const VkPipelineStageFlags*)DE_NULL, // pWaitDstStageMask - 1, // commandBufferCount - &primCmdBufTwo.get(), // pCommandBuffers - 0u, // signalSemaphoreCount - DE_NULL, // pSignalSemaphores + VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; + &timelineWaitSubmitInfo, // const void* pNext; + 1u, // uint32_t waitSemaphoreCount; + &semaphore.get(), // const VkSemaphore* pWaitSemaphores; + &semaphoreWaitStage, // const VkPipelineStageFlags* pWaitDstStageMask; + 1u, // uint32_t commandBufferCount; + &primCmdBufTwo.get(), // const VkCommandBuffer* pCommandBuffers; + 0u, // uint32_t signalSemaphoreCount; + nullptr, // const VkSemaphore* pSignalSemaphores; }; - // submit second primary buffer, the secondary should be executed too - VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfoTwo, *fenceTwo)); + VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo2, *fenceTwo)); - // wait for all buffers to stop at event for 100 microseconds - vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, 100000); + // Signal from host + const vk::VkSemaphoreSignalInfo signalInfo = + { + vk::VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, // VkStructureType sType; + nullptr, // const void* pNext; + semaphore.get(), // VkSemaphore semaphore; + semaphoreWaitValue, // uint64_t value; + }; - // now all buffers are waiting at eventOne - // set event eventOne - VK_CHECK(vk.setEvent(vkDevice, *eventOne)); + VK_CHECK(vk.signalSemaphore(vkDevice, &signalInfo)); // wait for end of execution of fenceOne VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceOne.get(), 0u, INFINITE_TIMEOUT)); - // wait for end of execution of second queue + // wait for end of execution of fenceTwo VK_CHECK(vk.waitForFences(vkDevice, 1, &fenceTwo.get(), 0u, INFINITE_TIMEOUT)); + TCU_CHECK(vk.getEventStatus(vkDevice, *eventOne) == vk::VK_EVENT_SET); + return tcu::TestStatus::pass("executeSecondaryBufferTwiceTest succeeded"); } @@ -3932,6 +3947,17 @@ void checkEventSupport (Context& context) TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation"); } +void checkTimelineSemaphoreSupport(Context& context) +{ + context.requireDeviceFunctionality("VK_KHR_timeline_semaphore"); +} + +void checkEventAndTimelineSemaphoreSupport(Context &context) +{ + checkTimelineSemaphoreSupport(context); + checkEventSupport(context); +} + void checkEventSupport (Context& context, const VkCommandBufferLevel) { checkEventSupport(context); @@ -4590,7 +4616,7 @@ tcu::TestCaseGroup* createCommandBuffersTests (tcu::TestContext& testCtx) addFunctionCase (commandBuffersTests.get(), "submit_two_buffers_one_buffer_null_with_fence", "", checkEventSupport, submitTwoBuffersOneBufferNullWithFence); /* 19.5. Secondary Command Buffer Execution (5.6 in VK 1.0 Spec) */ addFunctionCase (commandBuffersTests.get(), "secondary_execute", "", checkEventSupport, executeSecondaryBufferTest); - addFunctionCase (commandBuffersTests.get(), "secondary_execute_twice", "", checkEventSupport, executeSecondaryBufferTwiceTest); + addFunctionCase (commandBuffersTests.get(), "secondary_execute_twice", "", checkEventAndTimelineSemaphoreSupport, executeSecondaryBufferTwiceTest); /* 19.6. Commands Allowed Inside Command Buffers (? in VK 1.0 Spec) */ addFunctionCaseWithPrograms (commandBuffersTests.get(), "order_bind_pipeline", "", genComputeSource, orderBindPipelineTest); /* Verify untested transitions between command buffer states */ diff --git a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp index 89856daab..4c0ed0bf4 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiExternalMemoryTests.cpp @@ -21,6 +21,7 @@ #include "vktApiExternalMemoryTests.hpp" #include "vktCustomInstancesDevices.hpp" +#include "../compute/vktComputeTestsUtil.hpp" #include "vktTestCaseUtil.hpp" #include "vkRefUtil.hpp" @@ -30,6 +31,10 @@ #include "vkMemUtil.hpp" #include "vkApiVersion.hpp" #include "vkImageUtil.hpp" +#include "vkObjUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkBarrierUtil.hpp" +#include "vkBufferWithMemory.hpp" #include "tcuTestLog.hpp" #include "tcuCommandLine.hpp" @@ -56,6 +61,8 @@ # include <dxgi1_2.h> #endif +#include <chrono> + using tcu::TestLog; using namespace vkt::ExternalMemoryUtil; @@ -67,6 +74,15 @@ namespace { +template<typename T, int size> +T multiplyComponents (const tcu::Vector<T, size>& v) +{ + T accum = 1; + for (int i = 0; i < size; ++i) + accum *= v[i]; + return accum; +} + std::string getFormatCaseName (vk::VkFormat format) { return de::toLower(de::toString(getFormatStr(format)).substr(10)); @@ -400,6 +416,15 @@ vk::VkQueue getQueue (const vk::DeviceInterface& vkd, return queue; } +uint32_t getMaxInvocations(const Context& context, uint32_t idx) +{ + const auto& vki = context.getInstanceInterface(); + const auto physicalDevice = context.getPhysicalDevice(); + const auto properties = vk::getPhysicalDeviceProperties(vki, physicalDevice); + + return properties.limits.maxComputeWorkGroupSize[idx]; +} + void checkSemaphoreSupport (const vk::InstanceInterface& vki, vk::VkPhysicalDevice device, vk::VkExternalSemaphoreHandleTypeFlagBits externalType) @@ -572,54 +597,180 @@ void submitEmptySignal (const vk::DeviceInterface& vkd, VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u)); } -void submitEmptySignalAndGetSemaphoreNative ( const vk::DeviceInterface& vk, - vk::VkDevice device, - vk::VkQueue queue, - deUint32 queueFamilyIndex, - vk::VkSemaphore semaphore, - vk::VkExternalSemaphoreHandleTypeFlagBits externalType, - NativeHandle& nativeHandle) +void tuneWorkSizeYAndPrepareCommandBuffer( const Context& context, + const vk::DeviceInterface& vk, + vk::VkDevice device, + vk::VkQueue queue, + vk::VkCommandBuffer cmdBuffer, + vk::VkDescriptorSet descriptorSet, + vk::VkPipelineLayout pipelineLayout, + vk::VkPipeline computePipeline, + vk::VkBufferMemoryBarrier computeFinishBarrier, + vk::VkEvent event, + tcu::UVec3* maxWorkSize) + + +{ + // Have it be static so we don't need to do tuning every time, especially for "export_multiple_times" tests. + static uint32_t yWorkSize = 1; + uint64_t timeElapsed = 0; + bool bOutLoop = false; + + const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device)); + + const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo = + { + vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + nullptr, + vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + nullptr, + }; + + while (true) { + VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo)); + + /* + * If the handle type is VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR, the spec allowed for implementations to return -1 + * if the fence is already signaled. Previously, to avoid getting -1 in this case, this test had used vkCmdWaitEvents and + * vkSetEvent after submission to get a proper file descriptor before signaling but it's not invalid to call vkSetEvent + * after submission. So we just use vkCmdSetEvent and check the state of the event after submission to see if it's already + * signaled or an error happens while trying to get a file descriptor. + */ + vk.cmdSetEvent(cmdBuffer, event, vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); + + // And now we do a simple atomic calculation to avoid signalling instantly right after submit. + vk.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline); + //vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, nullptr); + vk.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet, 0u, nullptr); + vk.cmdDispatch(cmdBuffer, maxWorkSize->x(), yWorkSize, maxWorkSize->z()); + vk.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 1u, &computeFinishBarrier, 0, nullptr); + vk.endCommandBuffer(cmdBuffer); + + if (bOutLoop) + break; + + const vk::VkSubmitInfo submit = + { + vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, + nullptr, + + 0u, + nullptr, + nullptr, + + 1u, + &cmdBuffer, + + 0u, + nullptr + }; + + auto timeStart = std::chrono::high_resolution_clock::now(); + + VK_CHECK(vk.queueSubmit(queue, 1, &submit, (vk::VkFence)*fence)); + vk.waitForFences(device, 1u, &fence.get(), true, ~0ull); + + const auto executionTime = std::chrono::high_resolution_clock::now() - timeStart; + auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(executionTime); + + timeElapsed = elapsed.count(); + + // we do loop until we get over 9 miliseconds as an execution time. + if (elapsed.count() > 9) + { + bOutLoop = true; + continue; + } + + yWorkSize *= 2; + + if (yWorkSize > maxWorkSize->y()) + { + yWorkSize = maxWorkSize->y(); + bOutLoop = true; + } + + vk.resetCommandBuffer(cmdBuffer, 0u); + vk.resetFences(device, 1u, &*fence); + }; + + tcu::TestLog& log = context.getTestContext().getLog(); + log << tcu::TestLog::Message + << "Execution time to get a native file descriptor is " << timeElapsed << "ms with Y WorkSize " << yWorkSize + << tcu::TestLog::EndMessage; + + return; +} + +void submitAtomicCalculationsAndGetSemaphoreNative (const Context& context, + const vk::DeviceInterface& vk, + vk::VkDevice device, + vk::Allocator& alloc, + vk::VkQueue queue, + deUint32 queueFamilyIndex, + vk::VkSemaphore semaphore, + vk::VkExternalSemaphoreHandleTypeFlagBits externalType, + NativeHandle& nativeHandle) { - const vk::Unique<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL)); + const vk::Unique<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex, nullptr)); const vk::Unique<vk::VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); const vk::VkEventCreateInfo eventCreateInfo = { vk::VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, - DE_NULL, + nullptr, 0u }; - const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL)); + const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, nullptr)); - const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo = - { - vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - DE_NULL, - vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, - DE_NULL, - }; + const uint32_t maxXWorkSize = getMaxInvocations(context, 0); + const uint32_t maxYWorkSize = getMaxInvocations(context, 1); + + tcu::UVec3 workSize = { maxXWorkSize, maxYWorkSize, 1u }; + const uint32_t workGroupCount = multiplyComponents(workSize); + + const vk::VkDeviceSize outputBufferSize = sizeof(uint32_t) * workGroupCount; + const vk::BufferWithMemory outputBuffer (vk, device, alloc, makeBufferCreateInfo(outputBufferSize, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::Local); - VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); - /* - The submitEmptySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a - VkSemaphore to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit - may signal the semaphore immediately. When a semaphore's file descriptor is obtained using vkGetFenceFdKHR, if the - handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 if the fence - is already signalled, instead of a file descriptor, . In order to make sure that a valid file descriptor is returned - we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence. - */ - vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL); - vk.endCommandBuffer(*cmdBuffer); + // Create a compute shader + const vk::Unique<vk::VkShaderModule> compShader(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0u)); + + // Create descriptorSetLayout + vk::DescriptorSetLayoutBuilder layoutBuilder; + layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT); + vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(layoutBuilder.build(vk, device)); + + // Create compute pipeline + const vk::Unique<vk::VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout)); + const vk::Unique<vk::VkPipeline> computePipeline(compute::makeComputePipeline(vk, device, *pipelineLayout, *compShader)); + + // Create descriptor pool + const vk::Unique<vk::VkDescriptorPool> descriptorPool( + vk::DescriptorPoolBuilder() + .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1)); + + + const vk::Move<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + const vk::VkDescriptorBufferInfo outputBufferInfo = makeDescriptorBufferInfo(*outputBuffer, 0ull, outputBufferSize); + const vk::VkBufferMemoryBarrier computeFinishBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0ull, outputBufferSize); + + vk::DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferInfo) + .update(vk, device); + + // Now start tuning work size of Y to have time enough to get a fd at the device. + tuneWorkSizeYAndPrepareCommandBuffer(context, vk, device, queue, *cmdBuffer, *descriptorSet, *pipelineLayout, *computePipeline, computeFinishBarrier, *event, &workSize); const vk::VkSubmitInfo submit = { vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, - DE_NULL, + nullptr, 0u, - DE_NULL, - DE_NULL, + nullptr, + nullptr, 1u, &cmdBuffer.get(), @@ -628,11 +779,14 @@ void submitEmptySignalAndGetSemaphoreNative ( const vk::DeviceInterface& vk &semaphore }; + VK_CHECK(vk.queueSubmit(queue, 1, &submit, (vk::VkFence)0u)); getSemaphoreNative(vk, device, semaphore, externalType, nativeHandle); - VK_CHECK(vk.setEvent(device, *event)); + // Allow -1, that is valid if signalled properly. + if (nativeHandle.getFd() == -1) + TCU_CHECK(vk.getEventStatus(device, *event) == vk::VK_EVENT_SET); VK_CHECK(vk.queueWaitIdle(queue)); } @@ -684,16 +838,18 @@ void submitEmptySignal (const vk::DeviceInterface& vkd, VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence)); } -void submitEmptySignalAndGetFenceNative ( const vk::DeviceInterface& vk, - vk::VkDevice device, - vk::VkQueue queue, - deUint32 queueFamilyIndex, - vk::VkFence fence, - vk::VkExternalFenceHandleTypeFlagBits externalType, - NativeHandle& nativeHandle, - bool expectFenceUnsignaled = true) +void submitAtomicCalculationsAndGetFenceNative (const Context& context, + const vk::DeviceInterface& vk, + vk::VkDevice device, + vk::Allocator& alloc, + vk::VkQueue queue, + deUint32 queueFamilyIndex, + vk::VkFence fence, + vk::VkExternalFenceHandleTypeFlagBits externalType, + NativeHandle& nativeHandle, + bool expectFenceUnsignaled = true) { - const vk::Unique<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL)); + const vk::Unique<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex, nullptr)); const vk::Unique<vk::VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); const vk::VkEventCreateInfo eventCreateInfo = @@ -703,27 +859,46 @@ void submitEmptySignalAndGetFenceNative ( const vk::DeviceInterface& vk, 0u }; - const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL)); + const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL)); - const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo = - { - vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - DE_NULL, - vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, - DE_NULL, - }; + const uint32_t maxXWorkSize = getMaxInvocations(context, 0); + const uint32_t maxYWorkSize = getMaxInvocations(context, 1); + + tcu::UVec3 workSize = { maxXWorkSize, maxYWorkSize, 1u }; + const uint32_t workGroupCount = multiplyComponents(workSize); - VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); - /* - The submitEmptySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a - VkFence to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit - could signal the fence immediately. When a fence's file descriptor is obtained using vkGetFenceFdKHR, if the - handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 instead of a - file descriptor, if the fence is already signalled. In order to make sure that a valid file descriptor is returned - we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence. - */ - vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL); - vk.endCommandBuffer(*cmdBuffer); + const vk::VkDeviceSize outputBufferSize = sizeof(uint32_t) * workGroupCount; + const vk::BufferWithMemory outputBuffer (vk, device, alloc, makeBufferCreateInfo(outputBufferSize, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), vk::MemoryRequirement::Local); + + // Create a compute shader + const vk::Unique<vk::VkShaderModule> compShader(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0u)); + + // Create descriptorSetLayout + vk::DescriptorSetLayoutBuilder layoutBuilder; + layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT); + vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(layoutBuilder.build(vk, device)); + + // Create compute pipeline + const vk::Unique<vk::VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout)); + const vk::Unique<vk::VkPipeline> computePipeline(compute::makeComputePipeline(vk, device, *pipelineLayout, *compShader)); + + // Create descriptor pool + const vk::Unique<vk::VkDescriptorPool> descriptorPool( + vk::DescriptorPoolBuilder() + .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1)); + + + const vk::Move<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + const vk::VkDescriptorBufferInfo outputBufferInfo = makeDescriptorBufferInfo(*outputBuffer, 0ull, outputBufferSize); + const vk::VkBufferMemoryBarrier computeFinishBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0ull, outputBufferSize); + + vk::DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferInfo) + .update(vk, device); + + // Now start tuning work size of Y to have time enough to get a fd at the device. + tuneWorkSizeYAndPrepareCommandBuffer(context, vk, device, queue, *cmdBuffer, *descriptorSet, *pipelineLayout, *computePipeline, computeFinishBarrier, *event, &workSize); const vk::VkSubmitInfo submit = { @@ -744,8 +919,9 @@ void submitEmptySignalAndGetFenceNative ( const vk::DeviceInterface& vk, VK_CHECK(vk.queueSubmit(queue, 1, &submit, fence)); getFenceNative(vk, device, fence, externalType, nativeHandle, expectFenceUnsignaled); - - VK_CHECK(vk.setEvent(device, *event)); + // Allow -1, that is valid if signalled properly. + if (nativeHandle.getFd() == -1) + TCU_CHECK(vk.getEventStatus(device, *event) == vk::VK_EVENT_SET); VK_CHECK(vk.queueWaitIdle(queue)); } @@ -795,6 +971,26 @@ struct SemaphoreTestConfig Permanence permanence; }; +template<class TestConfig> void initProgramsToGetNativeFd(vk::SourceCollections& dst, const TestConfig) +{ + const tcu::IVec3 localSize = { 64, 1, 1 }; + + std::ostringstream src; + src << "#version 310 es\n" + << "layout (local_size_x = " << localSize.x() << ", local_size_y = " << localSize.y() << ", local_size_z = " << localSize.z() << ") in;\n" + << "layout(binding = 0) writeonly buffer Output {\n" + << " uint values[];\n" + << "};\n" + << "\n" + << "void main (void) {\n" + << " uint offset = gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_WorkGroupID.z + gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;\n" + << "\n" + << " atomicAdd(values[offset], 1u);\n" + << "}\n"; + + dst.glslSources.add("compute") << glu::ComputeSource(src.str()); +} + tcu::TestStatus testSemaphoreWin32Create (Context& context, const SemaphoreTestConfig config) { @@ -882,12 +1078,17 @@ tcu::TestStatus testSemaphoreImportTwice (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handleA); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphore, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA); @@ -929,13 +1130,18 @@ tcu::TestStatus testSemaphoreImportReimport (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA); @@ -969,18 +1175,22 @@ tcu::TestStatus testSemaphoreSignalExportImportWait (Context& context, const vk::InstanceDriver& vki (instance.getDriver()); const vk::VkPhysicalDevice physicalDevice (vk::chooseDevice(vki, instance, context.getTestContext().getCommandLine())); const deUint32 queueFamilyIndex (chooseQueueFamilyIndex(vki, physicalDevice, 0u)); + const Transference transference (getHandelTypeTransferences(config.externalType)); checkSemaphoreSupport(vki, physicalDevice, config.externalType); { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); { NativeHandle handle; - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + if (transference == TRANSFERENCE_COPY && handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); { const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; @@ -1053,7 +1263,7 @@ tcu::TestStatus testSemaphoreExportImportSignalWait (Context& context, const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); NativeHandle handle; - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle); const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags)); @@ -1082,6 +1292,7 @@ tcu::TestStatus testSemaphoreSignalImport (Context& context, const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); @@ -1092,7 +1303,11 @@ tcu::TestStatus testSemaphoreSignalImport (Context& context, VK_CHECK(vkd.queueWaitIdle(queue)); if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle); @@ -1117,7 +1332,6 @@ tcu::TestStatus testSemaphoreSignalImport (Context& context, tcu::TestStatus testSemaphoreSignalWaitImport (Context& context, const SemaphoreTestConfig config) { - const Transference transference (getHandelTypeTransferences(config.externalType)); const vk::PlatformInterface& vkp (context.getPlatformInterface()); const CustomInstance instance (createTestInstance(context, config.externalType, 0u, 0u)); const vk::InstanceDriver& vki (instance.getDriver()); @@ -1136,10 +1350,7 @@ tcu::TestStatus testSemaphoreSignalWaitImport (Context& context, const vk::Unique<vk::VkSemaphore> semaphoreB (createSemaphore(vkd, *device)); NativeHandle handle; - if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); - else - getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle); + getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle); submitEmptySignal(vkd, queue, *semaphoreB); submitEmptyWait(vkd, queue, *semaphoreB); @@ -1148,15 +1359,8 @@ tcu::TestStatus testSemaphoreSignalWaitImport (Context& context, importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags); - if (transference == TRANSFERENCE_COPY) - submitEmptyWait(vkd, queue, *semaphoreB); - else if (transference == TRANSFERENCE_REFERENCE) - { - submitEmptySignal(vkd, queue, *semaphoreA); - submitEmptyWait(vkd, queue, *semaphoreB); - } - else - DE_FATAL("Unknown transference."); + submitEmptySignal(vkd, queue, *semaphoreA); + submitEmptyWait(vkd, queue, *semaphoreB); VK_CHECK(vkd.queueWaitIdle(queue)); @@ -1193,7 +1397,7 @@ tcu::TestStatus testSemaphoreImportSyncFdSignaled (Context& context, tcu::TestStatus testSemaphoreMultipleExports (Context& context, const SemaphoreTestConfig config) { - const size_t exportCount = 4 * 1024; + const size_t exportCount = 1024; const Transference transference (getHandelTypeTransferences(config.externalType)); const vk::PlatformInterface& vkp (context.getPlatformInterface()); const CustomInstance instance (createTestInstance(context, config.externalType, 0u, 0u)); @@ -1206,6 +1410,7 @@ tcu::TestStatus testSemaphoreMultipleExports (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphore (createExportableSemaphore(vkd, *device, config.externalType)); @@ -1214,7 +1419,11 @@ tcu::TestStatus testSemaphoreMultipleExports (Context& context, NativeHandle handle; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handle); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphore, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle); } @@ -1245,12 +1454,17 @@ tcu::TestStatus testSemaphoreMultipleImports (Context& context, const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA); @@ -1295,12 +1509,15 @@ tcu::TestStatus testSemaphoreTransference (Context& context, const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkSemaphore> semaphoreA (createExportableSemaphore(vkd, *device, config.externalType)); NativeHandle handle; - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle); + if (transference == TRANSFERENCE_COPY && handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); { const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, handle, flags)); @@ -1388,6 +1605,7 @@ tcu::TestStatus testSemaphoreFdDup (Context& context, const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -1397,7 +1615,11 @@ tcu::TestStatus testSemaphoreFdDup (Context& context, NativeHandle fd; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); + if (fd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd); @@ -1451,6 +1673,7 @@ tcu::TestStatus testSemaphoreFdDup2 (Context& context, const vk::VkSemaphoreImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -1462,8 +1685,10 @@ tcu::TestStatus testSemaphoreFdDup2 (Context& context, if (transference == TRANSFERENCE_COPY) { - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd); + if (fd.getFd() == -1 || secondFd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); } else { @@ -1520,6 +1745,7 @@ tcu::TestStatus testSemaphoreFdDup3 (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -1531,8 +1757,10 @@ tcu::TestStatus testSemaphoreFdDup3 (Context& context, if (transference == TRANSFERENCE_COPY) { - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd); + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd); + if (fd.getFd() == -1 || secondFd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); } else { @@ -1590,6 +1818,7 @@ tcu::TestStatus testSemaphoreFdSendOverSocket (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -1597,7 +1826,11 @@ tcu::TestStatus testSemaphoreFdSendOverSocket (Context& context, NativeHandle fd; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, fd); + { + submitAtomicCalculationsAndGetSemaphoreNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *semaphore, config.externalType, fd); + if (fd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getSemaphoreNative(vkd, *device, *semaphore, config.externalType, fd); @@ -1759,7 +1992,6 @@ struct FenceTestConfig Permanence permanence; }; - tcu::TestStatus testFenceWin32Create (Context& context, const FenceTestConfig config) { @@ -1847,12 +2079,17 @@ tcu::TestStatus testFenceImportTwice (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handleA); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fence, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fence, config.externalType, handleA); @@ -1894,13 +2131,18 @@ tcu::TestStatus testFenceImportReimport (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fenceA, config.externalType, handleA); @@ -1940,13 +2182,16 @@ tcu::TestStatus testFenceSignalExportImportWait (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); { NativeHandle handle; - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); { const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; @@ -2073,6 +2318,7 @@ tcu::TestStatus testFenceSignalImport (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); @@ -2083,7 +2329,11 @@ tcu::TestStatus testFenceSignalImport (Context& context, VK_CHECK(vkd.queueWaitIdle(queue)); if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fenceA, config.externalType, handle); @@ -2121,6 +2371,7 @@ tcu::TestStatus testFenceReset (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); @@ -2131,7 +2382,10 @@ tcu::TestStatus testFenceReset (Context& context, submitEmptySignal(vkd, queue, *fenceB); VK_CHECK(vkd.queueWaitIdle(queue)); - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + NativeHandle handleB (handle); importFence(vkd, *device, *fenceB, config.externalType, handleB, flags); importFence(vkd, *device, *fenceC, config.externalType, handle, flags); @@ -2173,7 +2427,6 @@ tcu::TestStatus testFenceReset (Context& context, tcu::TestStatus testFenceSignalWaitImport (Context& context, const FenceTestConfig config) { - const Transference transference (getHandelTypeTransferences(config.externalType)); const vk::PlatformInterface& vkp (context.getPlatformInterface()); const CustomInstance instance (createTestInstance(context, 0u, 0u, config.externalType)); const vk::InstanceDriver& vki (instance.getDriver()); @@ -2192,10 +2445,7 @@ tcu::TestStatus testFenceSignalWaitImport (Context& context, const vk::Unique<vk::VkFence> fenceB (createFence(vkd, *device)); NativeHandle handle; - if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle); - else - getFenceNative(vkd, *device, *fenceA, config.externalType, handle); + getFenceNative(vkd, *device, *fenceA, config.externalType, handle); submitEmptySignal(vkd, queue, *fenceB); VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull)); @@ -2204,15 +2454,8 @@ tcu::TestStatus testFenceSignalWaitImport (Context& context, importFence(vkd, *device, *fenceB, config.externalType, handle, flags); - if (transference == TRANSFERENCE_COPY) - VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull)); - else if (transference == TRANSFERENCE_REFERENCE) - { - submitEmptySignal(vkd, queue, *fenceA); - VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull)); - } - else - DE_FATAL("Unknown transference."); + submitEmptySignal(vkd, queue, *fenceA); + VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull)); VK_CHECK(vkd.queueWaitIdle(queue)); @@ -2223,7 +2466,7 @@ tcu::TestStatus testFenceSignalWaitImport (Context& context, tcu::TestStatus testFenceMultipleExports (Context& context, const FenceTestConfig config) { - const size_t exportCount = 4 * 1024; + const size_t exportCount = 1024; const Transference transference (getHandelTypeTransferences(config.externalType)); const vk::PlatformInterface& vkp (context.getPlatformInterface()); const CustomInstance instance (createTestInstance(context, 0u, 0u, config.externalType)); @@ -2236,6 +2479,7 @@ tcu::TestStatus testFenceMultipleExports (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fence (createExportableFence(vkd, *device, config.externalType)); @@ -2244,7 +2488,11 @@ tcu::TestStatus testFenceMultipleExports (Context& context, NativeHandle handle; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handle, exportNdx == 0 /* expect fence to be signaled after first pass */); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fence, config.externalType, handle, exportNdx == 0 /* expect fence to be signaled after first pass */); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fence, config.externalType, handle, exportNdx == 0 /* expect fence to be signaled after first pass */); } @@ -2275,12 +2523,17 @@ tcu::TestStatus testFenceMultipleImports (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); NativeHandle handleA; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handleA); + if (handleA.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fenceA, config.externalType, handleA); @@ -2325,12 +2578,15 @@ tcu::TestStatus testFenceTransference (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); const vk::Unique<vk::VkFence> fenceA (createExportableFence(vkd, *device, config.externalType)); NativeHandle handle; - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, handle); + if (handle.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); { const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, handle, flags)); @@ -2424,6 +2680,7 @@ tcu::TestStatus testFenceFdDup (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -2433,7 +2690,11 @@ tcu::TestStatus testFenceFdDup (Context& context, NativeHandle fd; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, fd); + if (fd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fenceA, config.externalType, fd); @@ -2487,6 +2748,7 @@ tcu::TestStatus testFenceFdDup2 (Context& context, const vk::VkFenceImportFlags flags = config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u; const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -2498,8 +2760,10 @@ tcu::TestStatus testFenceFdDup2 (Context& context, if (transference == TRANSFERENCE_COPY) { - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd); - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, fd); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd); + if (fd.getFd() == -1 || secondFd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); } else { @@ -2556,6 +2820,7 @@ tcu::TestStatus testFenceFdDup3 (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -2567,8 +2832,10 @@ tcu::TestStatus testFenceFdDup3 (Context& context, if (transference == TRANSFERENCE_COPY) { - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd); - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceA, config.externalType, fd); + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd); + if (fd.getFd() == -1 || secondFd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); } else { @@ -2626,6 +2893,7 @@ tcu::TestStatus testFenceFdSendOverSocket (Context& context, { const vk::Unique<vk::VkDevice> device (createTestDevice(context, vkp, instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex)); const vk::DeviceDriver vkd (vkp, instance, *device); + vk::SimpleAllocator alloc (vkd, *device, vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice)); const vk::VkQueue queue (getQueue(vkd, *device, queueFamilyIndex)); TestLog& log = context.getTestContext().getLog(); @@ -2633,7 +2901,11 @@ tcu::TestStatus testFenceFdSendOverSocket (Context& context, NativeHandle fd; if (transference == TRANSFERENCE_COPY) - submitEmptySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, fd); + { + submitAtomicCalculationsAndGetFenceNative(context, vkd, *device, alloc, queue, queueFamilyIndex, *fence, config.externalType, fd); + if (fd.getFd() == -1) + return tcu::TestStatus::pass("Pass: got -1 as a file descriptor, which is valid with a handle type of copy transference"); + } else getFenceNative(vkd, *device, *fence, config.externalType, fd); @@ -3975,29 +4247,29 @@ de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk: addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName, "Test creating fence with win32 properties.", testFenceWin32Create, config); } - addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName, "Test importing fence twice.", checkSupport, testFenceImportTwice, config); - addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported fence.", checkSupport, testFenceImportReimport, config); - addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing fence multiple times.", checkSupport, testFenceMultipleImports, config); - addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", checkEvent, testFenceSignalExportImportWait, config); - addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the fence.", checkSupport, testFenceSignalImport, config); - addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName, "Test resetting the fence.", checkEvent, testFenceReset, config); - addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName, "Test fences transference.", checkEvent, testFenceTransference, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("import_twice_") + permanenceName, "Test importing fence twice.", checkSupport, initProgramsToGetNativeFd, testFenceImportTwice, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported fence.", checkSupport, initProgramsToGetNativeFd, testFenceImportReimport, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing fence multiple times.", checkSupport, initProgramsToGetNativeFd, testFenceMultipleImports, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", checkEvent, initProgramsToGetNativeFd, testFenceSignalExportImportWait, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the fence.", checkSupport, initProgramsToGetNativeFd, testFenceSignalImport, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("reset_") + permanenceName, "Test resetting the fence.", checkEvent, initProgramsToGetNativeFd, testFenceReset, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("transference_") + permanenceName, "Test fences transference.", checkEvent, initProgramsToGetNativeFd, testFenceTransference, config); if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) { - addFunctionCase(fenceGroup.get(), std::string("import_signaled_") + permanenceName, "Test import signaled fence fd.", testFenceImportSyncFdSignaled, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("import_signaled_") + permanenceName, "Test import signaled fence fd.", initProgramsToGetNativeFd, testFenceImportSyncFdSignaled, config); } if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT) { // \note Not supported on WIN32 handles - addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting fence multiple times.", checkSupport, testFenceMultipleExports, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting fence multiple times.", checkSupport, initProgramsToGetNativeFd, testFenceMultipleExports, config); - addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported fence.", checkSupport, testFenceFdDup, config); - addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported fence.", checkSupport, testFenceFdDup2, config); - addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported fence.", checkSupport, testFenceFdDup3, config); - addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending fence fd over socket.", checkSupport, testFenceFdSendOverSocket, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported fence.", checkSupport, initProgramsToGetNativeFd, testFenceFdDup, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported fence.", checkSupport, initProgramsToGetNativeFd, testFenceFdDup2, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported fence.", checkSupport, initProgramsToGetNativeFd, testFenceFdDup3, config); + addFunctionCaseWithPrograms(fenceGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending fence fd over socket.", checkSupport, initProgramsToGetNativeFd, testFenceFdSendOverSocket, config); } if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE) @@ -4376,16 +4648,16 @@ de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName, "Test creating semaphore with win32 properties.", testSemaphoreWin32Create, config); } - addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName, "Test importing semaphore twice.", checkSupport, testSemaphoreImportTwice, config); - addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported semaphore.", checkSupport, testSemaphoreImportReimport, config); - addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing semaphore multiple times.", checkSupport, testSemaphoreMultipleImports, config); - addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", checkEvent, testSemaphoreSignalExportImportWait, config); - addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the semaphore.", checkSupport, testSemaphoreSignalImport, config); - addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName, "Test semaphores transference.", checkEvent, testSemaphoreTransference, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("import_twice_") + permanenceName, "Test importing semaphore twice.", checkSupport, initProgramsToGetNativeFd, testSemaphoreImportTwice, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("reimport_") + permanenceName, "Test importing again over previously imported semaphore.", checkSupport, initProgramsToGetNativeFd, testSemaphoreImportReimport, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName, "Test importing semaphore multiple times.", checkSupport, initProgramsToGetNativeFd, testSemaphoreMultipleImports, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName, "Test signaling, exporting, importing and waiting for the sempahore.", checkEvent, initProgramsToGetNativeFd, testSemaphoreSignalExportImportWait, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("signal_import_") + permanenceName, "Test signaling and importing the semaphore.", checkSupport, initProgramsToGetNativeFd, testSemaphoreSignalImport, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("transference_") + permanenceName, "Test semaphores transference.", checkEvent, initProgramsToGetNativeFd, testSemaphoreTransference, config); if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) { - addFunctionCase(semaphoreGroup.get(), std::string("import_signaled_") + permanenceName, "Test import signaled semaphore fd.", testSemaphoreImportSyncFdSignaled, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("import_signaled_") + permanenceName, "Test import signaled semaphore fd.", initProgramsToGetNativeFd, testSemaphoreImportSyncFdSignaled, config); } @@ -4393,12 +4665,12 @@ de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) { // \note Not supported on WIN32 handles - addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting semaphore multiple times.", checkSupport, testSemaphoreMultipleExports, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName, "Test exporting semaphore multiple times.", checkSupport, initProgramsToGetNativeFd, testSemaphoreMultipleExports, config); - addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported semaphore.", checkSupport, testSemaphoreFdDup, config); - addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported semaphore.", checkSupport, testSemaphoreFdDup2, config); - addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported semaphore.", checkSupport, testSemaphoreFdDup3, config); - addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending semaphore fd over socket.", checkSupport, testSemaphoreFdSendOverSocket, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("dup_") + permanenceName, "Test calling dup() on exported semaphore.", checkSupport, initProgramsToGetNativeFd, testSemaphoreFdDup, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("dup2_") + permanenceName, "Test calling dup2() on exported semaphore.", checkSupport, initProgramsToGetNativeFd, testSemaphoreFdDup2, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("dup3_") + permanenceName, "Test calling dup3() on exported semaphore.", checkSupport, initProgramsToGetNativeFd, testSemaphoreFdDup3, config); + addFunctionCaseWithPrograms(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName, "Test sending semaphore fd over socket.", checkSupport, initProgramsToGetNativeFd, testSemaphoreFdSendOverSocket, config); } if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE) diff --git a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp index 2fc1a2e29..17524cbcb 100644 --- a/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp +++ b/external/vulkancts/modules/vulkan/image/vktImageCompressionTranscodingSupport.cpp @@ -542,7 +542,7 @@ TestStatus BasicComputeTestInstance::iterate (void) Allocator& allocator = m_context.getDefaultAllocator(); const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); - const UVec3 fullSize (m_parameters.size.x(), m_parameters.size.y(), 1); + const UVec3 fullSize (m_parameters.size.x(), m_parameters.imageType == IMAGE_TYPE_1D ? 1 : m_parameters.size.y(), 1); const vector<UVec3> mipMapSizes = m_parameters.useMipmaps ? getMipLevelSizes (getLayerDims()) : vector<UVec3>(1, fullSize); vector<ImageData> imageData (m_parameters.imagesCount); const deUint32 compressedNdx = 0u; @@ -1026,7 +1026,7 @@ bool BasicComputeTestInstance::decompressImage (const VkCommandBuffer& cmdBuffer { const bool layoutShaderReadOnly = (layerNdx % 2u) == 1; const deUint32 imageNdx = layerNdx + mipNdx * getLayerCount(); - const VkExtent3D extentCompressed = imageType == VK_IMAGE_TYPE_1D ? makeExtent3D(mipMapSizes[mipNdx].x(), 1, mipMapSizes[mipNdx].z()) : makeExtent3D(mipMapSizes[mipNdx]); + const VkExtent3D extentCompressed = makeExtent3D(mipMapSizes[mipNdx]); const VkImage& uncompressed = imageData[m_parameters.imagesCount -1].getImage(imageNdx); const VkExtent3D extentUncompressed = imageData[m_parameters.imagesCount -1].getImageInfo(imageNdx).extent; const VkDeviceSize bufferSizeComp = getCompressedImageSizeInBytes(m_parameters.formatCompressed, mipMapSizes[mipNdx]); diff --git a/external/vulkancts/modules/vulkan/memory/vktMemoryExternalMemoryHostTests.cpp b/external/vulkancts/modules/vulkan/memory/vktMemoryExternalMemoryHostTests.cpp index d5d3e50e4..c340f265a 100644 --- a/external/vulkancts/modules/vulkan/memory/vktMemoryExternalMemoryHostTests.cpp +++ b/external/vulkancts/modules/vulkan/memory/vktMemoryExternalMemoryHostTests.cpp @@ -169,7 +169,6 @@ protected: Move<VkCommandBuffer> m_cmdBufferCopy; Move<VkFence> m_fence_1; Move<VkFence> m_fence_2; - Move<VkEvent> m_event; }; ExternalMemoryHostBaseTestInstance::ExternalMemoryHostBaseTestInstance (Context& context, VkDeviceSize allocationSize) @@ -843,8 +842,6 @@ tcu::TestStatus ExternalMemoryHostSynchronizationTestInstance::iterate () m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); m_cmdBuffer = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); m_cmdBufferCopy = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); - - m_event = createEvent(m_vkd, m_device); m_fence_1 = createFence(m_vkd, m_device); m_fence_2 = createFence(m_vkd, m_device); @@ -860,7 +857,35 @@ tcu::TestStatus ExternalMemoryHostSynchronizationTestInstance::iterate () endCommandBuffer(m_vkd, *m_cmdBufferCopy); submitCommands(*m_cmdBuffer, *m_fence_1); - submitCommands(*m_cmdBufferCopy, *m_fence_2); + + const uint64_t semaphoreWaitValue = 1ull; + const VkPipelineStageFlags semaphoreWaitStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + const auto semaphore = createSemaphoreType(m_vkd, m_device, VK_SEMAPHORE_TYPE_TIMELINE); + + // Use timeline semaphore to signal from host. + const VkTimelineSemaphoreSubmitInfo timelineWaitSubmitInfo = + { + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, // VkStructureType sType; + nullptr, // const void* pNext; + 1u, // uint32_t waitSemaphoreValueCount; + &semaphoreWaitValue, // const uint64_t* pWaitSemaphoreValues; + 0u, // uint32_t signalSemaphoreValueCount; + nullptr, // const uint64_t* pSignalSemaphoreValues; + }; + + const VkSubmitInfo submit = + { + VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; + &timelineWaitSubmitInfo, // const void* pNext; + 1u, // uint32_t waitSemaphoreCount; + &semaphore.get(), // const VkSemaphore* pWaitSemaphores; + &semaphoreWaitStage, // const VkPipelineStageFlags* pWaitDstStageMask; + 1u, // uint32_t commandBufferCount; + &m_cmdBufferCopy.get(), // const VkCommandBuffer* pCommandBuffers; + 0u, // uint32_t signalSemaphoreCount; + nullptr, // const VkSemaphore* pSignalSemaphores; + }; + VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submit, *m_fence_2)); //wait for fence_1 and modify image on host VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_1.get(), DE_TRUE, ~0ull)); @@ -873,7 +898,17 @@ tcu::TestStatus ExternalMemoryHostSynchronizationTestInstance::iterate () if (deMemCmp(m_hostMemoryAlloc, pointerReturnedByMapMemory, (size_t)dataBufferSize) != 0) TCU_FAIL("Failed memcmp check."); m_vkd.unmapMemory(m_device, *m_deviceMemoryAllocatedFromHostPointer); - VK_CHECK(m_vkd.setEvent(m_device, *m_event)); + + // Signal from host + const vk::VkSemaphoreSignalInfo signalInfo = + { + vk::VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, // VkStructureType sType; + nullptr, // const void* pNext; + semaphore.get(), // VkSemaphore semaphore; + semaphoreWaitValue, // uint64_t value; + }; + + VK_CHECK(m_vkd.signalSemaphore(m_device, &signalInfo)); //wait for fence_2 before checking result VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_2.get(), DE_TRUE, ~0ull)); @@ -912,19 +947,6 @@ void ExternalMemoryHostSynchronizationTestInstance::prepareBufferForHostAccess ( void ExternalMemoryHostSynchronizationTestInstance::copyResultBuffertoBuffer (VkDeviceSize size) { - const VkBufferMemoryBarrier bufferBarrier = - { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; - DE_NULL, // const void* pNext; - VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; - VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; - VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; - VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; - *m_dataBuffer, // VkBuffer buffer; - 0u, // VkDeviceSize offset; - size // VkDeviceSize size; - }; - const VkBufferCopy region_all = { 0, //VkDeviceSize srcOffset; @@ -932,7 +954,6 @@ void ExternalMemoryHostSynchronizationTestInstance::copyResultBuffertoBuffer (Vk size //VkDeviceSize size; }; - m_vkd.cmdWaitEvents(*m_cmdBufferCopy, 1, &m_event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, DE_NULL, 1, &bufferBarrier, 0, DE_NULL); m_vkd.cmdCopyBuffer(*m_cmdBufferCopy, *m_dataBuffer, *m_resultBuffer, 1, ®ion_all); } @@ -1067,11 +1088,10 @@ void checkSupport (Context& context) context.requireDeviceFunctionality("VK_EXT_external_memory_host"); } -void checkEvent (Context& context) +void checkTimelineSemaphore (Context& context) { checkSupport(context); - if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && !context.getPortabilitySubsetFeatures().events) - TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Events are not supported by this implementation"); + context.requireDeviceFunctionality("VK_KHR_timeline_semaphore"); } } // unnamed namespace @@ -1119,7 +1139,7 @@ tcu::TestCaseGroup* createMemoryExternalMemoryHostTests (tcu::TestContext& testC synchronization->addChild(new InstanceFactory1WithSupport<ExternalMemoryHostSynchronizationTestInstance, TestParams, FunctionSupport0, AddPrograms> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "synchronization", "synchronization", AddPrograms(), - TestParams(testFormats[0].format, true), checkEvent)); + TestParams(testFormats[0].format, true), checkTimelineSemaphore)); group->addChild(synchronization.release()); return group.release(); } diff --git a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp index 66f9e90f5..45ed86732 100644 --- a/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp +++ b/external/vulkancts/modules/vulkan/query_pool/vktQueryPoolStatisticsTests.cpp @@ -408,6 +408,7 @@ void clearBuffer (const DeviceInterface& vk, const VkDevice device, const de::Sh void* allocationData = allocation.getHostPtr(); invalidateAlloc(vk, device, allocation); deMemcpy(allocationData, &data[0], (size_t)bufferSizeBytes); + flushAlloc(vk, device, allocation); } class StatisticQueryTestInstance : public TestInstance diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildTests.cpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildTests.cpp index cfdb0b22e..5712ee4dc 100644 --- a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildTests.cpp +++ b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildTests.cpp @@ -447,7 +447,7 @@ de::MovePtr<BufferWithMemory> RayTracingBuildTestInstance::runTest (bool useGpuB { cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier); vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange); - cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier); + cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, &postImageBarrier); bottomLevelAccelerationStructures = initBottomAccelerationStructures(*cmdBuffer, useGpuBuild, workerThreadsCount); topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, useGpuBuild, workerThreadsCount, bottomLevelAccelerationStructures); diff --git a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp index cee510284..4cb73b177 100644 --- a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp +++ b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp @@ -614,7 +614,7 @@ void getFenceNative (const vk::DeviceInterface& vkd, if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT) { - TCU_CHECK(!expectFenceUnsignaled || (fd >= 0)); + TCU_CHECK(!expectFenceUnsignaled || (fd >= 0) || (fd == -1)); } else { @@ -803,7 +803,12 @@ void getSemaphoreNative (const vk::DeviceInterface& vkd, int fd = -1; VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd)); - TCU_CHECK(fd >= 0); + + if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) + TCU_CHECK(fd >= -1); + else + TCU_CHECK(fd >= 0); + nativeHandle = fd; } else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT |