From c3ee14dad9ffd7fdfe045a95191c9f0b1153d660 Mon Sep 17 00:00:00 2001 From: Arkadiusz Sarwa Date: Wed, 15 Jun 2016 16:52:29 +0200 Subject: [PATCH] Added tests for internally synchronized objects --- .../vulkan/synchronization/CMakeLists.txt | 2 + ...tionInternallySynchronizedObjectsTests.cpp | 1190 +++++++++++++++++ ...tionInternallySynchronizedObjectsTests.hpp | 40 + .../vktSynchronizationTests.cpp | 2 + .../1.0.1/com.drawelements.deqp.vk.xml | 8 + .../vulkancts/mustpass/1.0.1/vk-default.txt | 2 + 6 files changed, 1244 insertions(+) create mode 100644 external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.cpp create mode 100644 external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.hpp diff --git a/external/vulkancts/modules/vulkan/synchronization/CMakeLists.txt b/external/vulkancts/modules/vulkan/synchronization/CMakeLists.txt index b67f6e3c7..f5f119b1a 100644 --- a/external/vulkancts/modules/vulkan/synchronization/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/synchronization/CMakeLists.txt @@ -19,6 +19,8 @@ set(DEQP_VK_SYNCHRONIZATION_SRCS vktSynchronizationOperationMultiQueueTests.hpp vktSynchronizationOperation.cpp vktSynchronizationOperation.hpp + vktSynchronizationInternallySynchronizedObjectsTests.cpp + vktSynchronizationInternallySynchronizedObjectsTests.hpp vktSynchronizationOperationTestData.hpp ) diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.cpp new file mode 100644 index 000000000..d87359256 --- /dev/null +++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.cpp @@ -0,0 +1,1190 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Synchronization internally synchronized objects tests + *//*--------------------------------------------------------------------*/ + +#include "vktSynchronizationInternallySynchronizedObjectsTests.hpp" +#include "vktTestCaseUtil.hpp" +#include "vktSynchronizationUtil.hpp" + +#include "vkRef.hpp" +#include "tcuDefs.hpp" +#include "vkTypeUtil.hpp" +#include "vkPlatform.hpp" +#include "vkBuilderUtil.hpp" +#include "vkImageUtil.hpp" + +#include "tcuResultCollector.hpp" + +#include "deThread.hpp" +#include "deMutex.hpp" +#include "deSharedPtr.hpp" + + +#include +#include + +namespace vkt +{ +namespace synchronization +{ +namespace +{ +using namespace vk; + +using std::vector; +using std::string; +using std::map; +using std::exception; +using std::ostringstream; + +using tcu::TestStatus; +using tcu::TestContext; +using tcu::ResultCollector; +using tcu::TestException; + +using de::UniquePtr; +using de::MovePtr; +using de::SharedPtr; +using de::Mutex; +using de::Thread; +using de::clamp; + +enum {EXECUTION_PER_THREAD = 100, BUFFER_ELEMENT_COUNT = 16, BUFFER_SIZE = BUFFER_ELEMENT_COUNT*4 }; + +class MultiQueues +{ + typedef struct QueueType + { + vector queues; + vector available; + } Queues; + +public: + + inline void addQueueFamilyIndex (const deUint32& queueFamilyIndex, const deUint32& count) + { + Queues temp; + vector::iterator it; + it = temp.available.begin(); + temp.available.insert(it, count, false); + + temp.queues.resize(count); + m_queues[queueFamilyIndex] = temp; + } + + const deUint32& getQueueFamilyIndex (const int index) + { + map::iterator it = m_queues.begin(); + advance (it, index); + return it->first; + } + + inline size_t countQueueFamilyIndex (void) + { + return m_queues.size(); + } + + Queues & getQueues (const int index) + { + map::iterator it = m_queues.begin(); + advance (it, index); + return it->second; + } + + bool getFreeQueue (deUint32& returnQueueFamilyIndex, VkQueue& returnQueues, int& returnQueueIndex) + { + for (int queueFamilyIndexNdx = 0 ; queueFamilyIndexNdx < static_cast(m_queues.size()); ++queueFamilyIndexNdx) + { + Queues& queue = m_queues[getQueueFamilyIndex(queueFamilyIndexNdx)]; + for (int queueNdx = 0; queueNdx < static_cast(queue.queues.size()); ++queueNdx) + { + m_mutex.lock(); + if (queue.available[queueNdx]) + { + queue.available[queueNdx] = false; + returnQueueFamilyIndex = getQueueFamilyIndex(queueFamilyIndexNdx); + returnQueues = queue.queues[queueNdx]; + returnQueueIndex = queueNdx; + m_mutex.unlock(); + return true; + } + m_mutex.unlock(); + } + } + return false; + } + + void releaseQueue (const deUint32& queueFamilyIndex, const int& queueIndex) + { + m_mutex.lock(); + m_queues[queueFamilyIndex].available[queueIndex] = true; + m_mutex.unlock(); + } + + inline void setDevice (Move device) + { + m_logicalDevice = device; + } + + inline VkDevice getDevice (void) + { + return *m_logicalDevice; + } + + MovePtr m_allocator; +protected: + Move m_logicalDevice; + map m_queues; + Mutex m_mutex; + +}; + +MovePtr createAllocator (const Context& context, const VkDevice& device) +{ + const DeviceInterface& deviceInterface = context.getDeviceInterface(); + const InstanceInterface& instance = context.getInstanceInterface(); + const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); + const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); + + // Create memory allocator for device + return MovePtr (new SimpleAllocator(deviceInterface, device, deviceMemoryProperties)); +} + +bool checkQueueFlags (const VkQueueFlags& availableFlag, const VkQueueFlags& neededFlag) +{ + if (VK_QUEUE_TRANSFER_BIT == neededFlag) + { + if ( (availableFlag & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT || + (availableFlag & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT || + (availableFlag & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT + ) + return true; + } + else if ((availableFlag & neededFlag) == neededFlag) + { + return true; + } + return false; +} + +MovePtr createQueues (const Context& context, const VkQueueFlags& queueFlag) +{ + const DeviceInterface& vk = context.getDeviceInterface(); + const InstanceInterface& instance = context.getInstanceInterface(); + const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); + MovePtr moveQueues (new MultiQueues()); + MultiQueues& queues = *moveQueues; + VkDeviceCreateInfo deviceInfo; + VkPhysicalDeviceFeatures deviceFeatures; + vector queueFamilyProperties; + vector queuePriorities; + vector queueInfos; + + queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice); + + for (deUint32 queuePropertiesNdx = 0; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx) + { + if (checkQueueFlags(queueFamilyProperties[queuePropertiesNdx].queueFlags, queueFlag)) + { + queues.addQueueFamilyIndex(queuePropertiesNdx, queueFamilyProperties[queuePropertiesNdx].queueCount); + } + } + + if (queues.countQueueFamilyIndex() == 0) + { + TCU_THROW(NotSupportedError, "Queue not found"); + } + + { + vector::iterator it = queuePriorities.begin(); + unsigned int maxQueueCount = 0; + for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx) + { + if (queues.getQueues(queueFamilyIndexNdx).queues.size() > maxQueueCount) + maxQueueCount = static_cast(queues.getQueues(queueFamilyIndexNdx).queues.size()); + } + queuePriorities.insert(it, maxQueueCount, 1.0); + } + + for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx) + { + VkDeviceQueueCreateInfo queueInfo; + const deUint32 queueCount = static_cast(queues.getQueues(queueFamilyIndexNdx).queues.size()); + + deMemset(&queueInfo, 0, sizeof(queueInfo)); + + queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueInfo.pNext = DE_NULL; + queueInfo.flags = (VkDeviceQueueCreateFlags)0u; + queueInfo.queueFamilyIndex = queues.getQueueFamilyIndex(queueFamilyIndexNdx); + queueInfo.queueCount = queueCount; + queueInfo.pQueuePriorities = &queuePriorities[0]; + + queueInfos.push_back(queueInfo); + } + + deMemset(&deviceInfo, 0, sizeof(deviceInfo)); + instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures); + + deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceInfo.pNext = DE_NULL; + deviceInfo.enabledExtensionCount = 0u; + deviceInfo.ppEnabledExtensionNames = DE_NULL; + deviceInfo.enabledLayerCount = 0u; + deviceInfo.ppEnabledLayerNames = DE_NULL; + deviceInfo.pEnabledFeatures = &deviceFeatures; + deviceInfo.queueCreateInfoCount = static_cast(queues.countQueueFamilyIndex()); + deviceInfo.pQueueCreateInfos = &queueInfos[0]; + + queues.setDevice(createDevice(instance, physicalDevice, &deviceInfo)); + + for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < queues.countQueueFamilyIndex(); ++queueFamilyIndex) + { + for (deUint32 queueReqNdx = 0; queueReqNdx < queues.getQueues(queueFamilyIndex).queues.size(); ++queueReqNdx) + { + vk.getDeviceQueue(queues.getDevice(), queues.getQueueFamilyIndex(queueFamilyIndex), queueReqNdx, &queues.getQueues(queueFamilyIndex).queues[queueReqNdx]); + queues.getQueues(queueFamilyIndex).available[queueReqNdx]=true; + } + } + + queues.m_allocator = createAllocator(context, queues.getDevice()); + return moveQueues; +} + +Move createRenderPass (const Context& context, const VkDevice& device, const VkFormat& colorFormat) +{ + const DeviceInterface& vk = context.getDeviceInterface(); + const VkAttachmentDescription colorAttachmentDescription = + { + 0u, // VkAttachmentDescriptionFlags flags; + colorFormat, // VkFormat format; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; + VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; + VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; + }; + const VkAttachmentReference colorAttachmentReference = + { + 0u, // deUint32 attachment; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; + }; + const VkSubpassDescription subpassDescription = + { + 0u, // VkSubpassDescriptionFlags flags; + VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; + 0u, // deUint32 inputAttachmentCount; + DE_NULL, // const VkAttachmentReference* pInputAttachments; + 1u, // deUint32 colorAttachmentCount; + &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; + DE_NULL, // const VkAttachmentReference* pResolveAttachments; + DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; + 0u, // deUint32 preserveAttachmentCount; + DE_NULL // const VkAttachmentReference* pPreserveAttachments; + }; + const VkRenderPassCreateInfo renderPassParams = + { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkRenderPassCreateFlags flags; + 1u, // deUint32 attachmentCount; + &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; + 1u, // deUint32 subpassCount; + &subpassDescription, // const VkSubpassDescription* pSubpasses; + 0u, // deUint32 dependencyCount; + DE_NULL // const VkSubpassDependency* pDependencies; + }; + return createRenderPass(vk, device, &renderPassParams); +} + +TestStatus executeComputePipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout, + const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const deUint32& shadersExecutions) +{ + const DeviceInterface& vk = context.getDeviceInterface(); + const VkDevice device = queues.getDevice(); + deUint32 queueFamilyIndex; + VkQueue queue; + int queueIndex; + while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){} + + { + const Unique descriptorPool (DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + Buffer resultBuffer (vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); + const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE); + const Unique cmdPool (makeCommandPool(vk, device, queueFamilyIndex)); + const Unique cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); + + { + const Allocation& alloc = resultBuffer.getAllocation(); + deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE); + flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), BUFFER_SIZE); + } + + // Start recording commands + beginCommandBuffer(vk, *cmdBuffer); + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); + + // Create descriptor set + const Unique descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout)); + + const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo) + .update(vk, device); + + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + + // Dispatch indirect compute command + vk.cmdDispatch(*cmdBuffer, shadersExecutions, 1u, 1u); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, + 0, (const VkMemoryBarrier*)DE_NULL, + 1, &bufferBarrier, + 0, (const VkImageMemoryBarrier*)DE_NULL); + + // End recording commands + endCommandBuffer(vk, *cmdBuffer); + + // Wait for command buffer execution finish + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + queues.releaseQueue(queueFamilyIndex, queueIndex); + + { + const Allocation& resultAlloc = resultBuffer.getAllocation(); + invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), BUFFER_SIZE); + + const deInt32* ptr = reinterpret_cast(resultAlloc.getHostPtr()); + for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx) + { + if (ptr[ndx] != ndx) + { + return TestStatus::fail("The data don't match"); + } + } + } + return TestStatus::pass("Passed"); + } +} + + +TestStatus executeGraphicPipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout, + const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const VkRenderPass& renderPass, const deUint32 shadersExecutions) +{ + const DeviceInterface& vk = context.getDeviceInterface(); + const VkDevice device = queues.getDevice(); + deUint32 queueFamilyIndex; + VkQueue queue; + int queueIndex; + while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){} + + { + const Unique descriptorPool (DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + Move descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout); + Buffer resultBuffer (vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); + const VkBufferMemoryBarrier bufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE); + const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; + const VkExtent3D colorImageExtent = makeExtent3D(1u, 1u, 1u); + const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + de::MovePtr colorAttachmentImage = de::MovePtr(new Image(vk, device, *queues.m_allocator, + makeImageCreateInfo(VK_IMAGE_TYPE_2D, colorImageExtent, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT), + MemoryRequirement::Any)); + Move colorAttachmentView = makeImageView(vk, device, **colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange); + Move framebuffer = makeFramebuffer(vk, device, renderPass, *colorAttachmentView, colorImageExtent.width, colorImageExtent.height, 1u); + const Unique cmdPool (makeCommandPool(vk, device, queueFamilyIndex)); + const Unique cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); + const VkDescriptorBufferInfo outputBufferDescriptorInfo = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo) + .update (vk, device); + + { + const Allocation& alloc = resultBuffer.getAllocation(); + deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE); + flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), BUFFER_SIZE); + } + + // Start recording commands + beginCommandBuffer(vk, *cmdBuffer); + // Change color attachment image layout + { + const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier( + (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + **colorAttachmentImage, colorImageSubresourceRange); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, + 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier); + } + + { + const VkRect2D renderArea = + { + makeOffset2D(0, 0), + makeExtent2D(1, 1), + }; + const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f); + beginRenderPass(vk, *cmdBuffer, renderPass, *framebuffer, renderArea, clearColor); + } + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + + vk.cmdDraw(*cmdBuffer, shadersExecutions, 1u, 0u, 0u); + endRenderPass(vk, *cmdBuffer); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, + 0, (const VkMemoryBarrier*)DE_NULL, + 1, &bufferBarrier, + 0, (const VkImageMemoryBarrier*)DE_NULL); + + // End recording commands + endCommandBuffer(vk, *cmdBuffer); + + // Wait for command buffer execution finish + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + queues.releaseQueue(queueFamilyIndex, queueIndex); + + { + const Allocation& resultAlloc = resultBuffer.getAllocation(); + invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), BUFFER_SIZE); + + const deInt32* ptr = reinterpret_cast(resultAlloc.getHostPtr()); + for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx) + { + if (ptr[ndx] != ndx) + { + return TestStatus::fail("The data don't match"); + } + } + } + return TestStatus::pass("Passed"); + } +} + + +class ThreadGroupThread : private Thread +{ +public: + ThreadGroupThread (const Context& context, VkPipelineCache pipelineCache, const VkPipelineLayout& pipelineLayout, + const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const vector& shadersExecutions) + : m_context (context) + , m_pipelineCache (pipelineCache) + , m_pipelineLayout (pipelineLayout) + , m_descriptorSetLayout (descriptorSetLayout) + , m_queues (queues) + , m_shadersExecutions (shadersExecutions) + { + } + + virtual ~ThreadGroupThread (void) + { + } + + ResultCollector& getResultCollector (void) + { + return m_resultCollector; + } + + using Thread::start; + using Thread::join; + +protected: + virtual TestStatus runThread () = 0; + const Context& m_context; + VkPipelineCache m_pipelineCache; + const VkPipelineLayout& m_pipelineLayout; + const VkDescriptorSetLayout& m_descriptorSetLayout; + MultiQueues& m_queues; + const vector& m_shadersExecutions; + +private: + ThreadGroupThread (const ThreadGroupThread&); + ThreadGroupThread& operator= (const ThreadGroupThread&); + + void run (void) + { + try + { + TestStatus result = runThread(); + m_resultCollector.addResult(result.getCode(), result.getDescription()); + } + catch (const TestException& e) + { + m_resultCollector.addResult(e.getTestResult(), e.getMessage()); + } + catch (const exception& e) + { + m_resultCollector.addResult(QP_TEST_RESULT_FAIL, e.what()); + } + catch (...) + { + m_resultCollector.addResult(QP_TEST_RESULT_FAIL, "Exception"); + } + } + + ResultCollector m_resultCollector; +}; + +class ThreadGroup +{ + typedef vector > ThreadVector; +public: + ThreadGroup (void) + { + } + ~ThreadGroup (void) + { + } + + void add (MovePtr thread) + { + m_threads.push_back(SharedPtr(thread.release())); + } + + TestStatus run (void) + { + ResultCollector resultCollector; + + for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter) + (*threadIter)->start(); + + for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter) + { + ResultCollector& threadResult = (*threadIter)->getResultCollector(); + (*threadIter)->join(); + resultCollector.addResult(threadResult.getResult(), threadResult.getMessage()); + } + + return TestStatus(resultCollector.getResult(), resultCollector.getMessage()); + } + +private: + ThreadVector m_threads; +}; + + +class CreateComputeThread : public ThreadGroupThread +{ +public: + CreateComputeThread (const Context& context, VkPipelineCache pipelineCache, vector& pipelineInfo, + const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout, + MultiQueues& queues, const vector& shadersExecutions) + : ThreadGroupThread (context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions) + , m_pipelineInfo (pipelineInfo) + { + } + + TestStatus runThread (void) + { + ResultCollector resultCollector; + for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx) + { + const int shaderNdx = executionNdx % m_pipelineInfo.size(); + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_queues.getDevice(); + Move pipeline = createComputePipeline(vk,device,m_pipelineCache, &m_pipelineInfo[shaderNdx]); + + TestStatus result = executeComputePipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_shadersExecutions[shaderNdx]); + resultCollector.addResult(result.getCode(), result.getDescription()); + } + return TestStatus(resultCollector.getResult(), resultCollector.getMessage()); + } +private: + vector& m_pipelineInfo; +}; + +class CreateGraphicThread : public ThreadGroupThread +{ +public: + CreateGraphicThread (const Context& context, VkPipelineCache pipelineCache, vector& pipelineInfo, + const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout, + MultiQueues& queues, const VkRenderPass& renderPass, const vector& shadersExecutions) + : ThreadGroupThread (context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions) + , m_pipelineInfo (pipelineInfo) + , m_renderPass (renderPass) + {} + + TestStatus runThread (void) + { + ResultCollector resultCollector; + for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx) + { + const int shaderNdx = executionNdx % m_pipelineInfo.size(); + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_queues.getDevice(); + Move pipeline = createGraphicsPipeline(vk,device, m_pipelineCache, &m_pipelineInfo[shaderNdx]); + + TestStatus result = executeGraphicPipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_renderPass, m_shadersExecutions[shaderNdx]); + resultCollector.addResult(result.getCode(), result.getDescription()); + } + return TestStatus(resultCollector.getResult(), resultCollector.getMessage()); + } + +private: + vector& m_pipelineInfo; + const VkRenderPass& m_renderPass; +}; + +class PipelineCacheComputeTestInstance : public TestInstance +{ + typedef vector > > ShaderModuleVector; +public: + PipelineCacheComputeTestInstance (Context& context, const vector& shadersExecutions) + : TestInstance (context) + , m_shadersExecutions (shadersExecutions) + + { + } + + TestStatus iterate (void) + { + const DeviceInterface& vk = m_context.getDeviceInterface(); + MovePtr queues = createQueues(m_context, VK_QUEUE_COMPUTE_BIT); + const VkDevice device = queues->getDevice(); + ShaderModuleVector shaderCompModules = addShaderModules(device); + Buffer resultBuffer (vk, device, *queues->m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); + const Move descriptorSetLayout (DescriptorSetLayoutBuilder() + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) + .build(vk, device)); + const Move pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); + vector shaderStageInfos = addShaderStageInfo(shaderCompModules); + vector pipelineInfo = addPipelineInfo(*pipelineLayout, shaderStageInfos); + const VkPipelineCacheCreateInfo pipelineCacheInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineCacheCreateFlags flags; + 0u, // deUintptr initialDataSize; + DE_NULL, // const void* pInitialData; + }; + Move pipelineCache = createPipelineCache(vk, device, &pipelineCacheInfo); + Move pipeline = createComputePipeline(vk, device, *pipelineCache, &pipelineInfo[0]); + const deUint32 numThreads = clamp(deGetNumAvailableLogicalCores(), 4u, 32u); + ThreadGroup threads; + + executeComputePipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions[0]); + + for (deUint32 ndx = 0; ndx < numThreads; ++ndx) + threads.add(MovePtr(new CreateComputeThread( + m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions))); + + { + TestStatus thread_result = threads.run(); + if(thread_result.getCode()) + { + return thread_result; + } + } + return TestStatus::pass("Passed"); + } + +private: + ShaderModuleVector addShaderModules (const VkDevice& device) + { + const DeviceInterface& vk = m_context.getDeviceInterface(); + ShaderModuleVector shaderCompModules; + shaderCompModules.resize(m_shadersExecutions.size()); + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()); ++shaderNdx) + { + ostringstream shaderName; + shaderName<<"compute_"< > (new Unique(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0))); + } + return shaderCompModules; + } + + vector addShaderStageInfo (const ShaderModuleVector& shaderCompModules) + { + VkPipelineShaderStageCreateInfo shaderStageInfo; + vector shaderStageInfos; + shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageInfo.pNext = DE_NULL; + shaderStageInfo.flags = (VkPipelineShaderStageCreateFlags)0; + shaderStageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + shaderStageInfo.pName = "main"; + shaderStageInfo.pSpecializationInfo = DE_NULL; + + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()); ++shaderNdx) + { + shaderStageInfo.module = *(*shaderCompModules[shaderNdx]); + shaderStageInfos.push_back(shaderStageInfo); + } + return shaderStageInfos; + } + + vector addPipelineInfo (VkPipelineLayout pipelineLayout, const vector& shaderStageInfos) + { + vector pipelineInfos; + VkComputePipelineCreateInfo computePipelineInfo; + computePipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineInfo.pNext = DE_NULL; + computePipelineInfo.flags = (VkPipelineCreateFlags)0; + computePipelineInfo.layout = pipelineLayout; + computePipelineInfo.basePipelineHandle = DE_NULL; + computePipelineInfo.basePipelineIndex = 0; + + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()); ++shaderNdx) + { + computePipelineInfo.stage = shaderStageInfos[shaderNdx]; + pipelineInfos.push_back(computePipelineInfo); + } + return pipelineInfos; + } + + const vector m_shadersExecutions; +}; + +class PipelineCacheGraphicTestInstance : public TestInstance +{ + typedef vector > > ShaderModuleVector; +public: + PipelineCacheGraphicTestInstance (Context& context, const vector& shadersExecutions) + : TestInstance (context) + , m_shadersExecutions (shadersExecutions) + + { + } + + TestStatus iterate (void) + { + requireFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); + + const DeviceInterface& vk = m_context.getDeviceInterface(); + MovePtr queues = createQueues (m_context, VK_QUEUE_GRAPHICS_BIT); + const VkDevice device = queues->getDevice(); + VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; + Move renderPass = createRenderPass(m_context, device, colorFormat); + const Move descriptorSetLayout (DescriptorSetLayoutBuilder() + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) + .build(vk, device)); + ShaderModuleVector shaderGraphicModules = addShaderModules(device); + const Move pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout)); + vector shaderStageInfos = addShaderStageInfo(shaderGraphicModules); + vector pipelineInfo = addPipelineInfo(*pipelineLayout, shaderStageInfos, *renderPass); + const VkPipelineCacheCreateInfo pipelineCacheInfo = + { + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineCacheCreateFlags flags; + 0u, // deUintptr initialDataSize; + DE_NULL, // const void* pInitialData; + }; + Move pipelineCache = createPipelineCache(vk, device, &pipelineCacheInfo); + Move pipeline = createGraphicsPipeline(vk, device, *pipelineCache, &pipelineInfo[0]); + const deUint32 numThreads = clamp(deGetNumAvailableLogicalCores(), 4u, 32u); + ThreadGroup threads; + + executeGraphicPipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions[0]); + + for (deUint32 ndx = 0; ndx < numThreads; ++ndx) + threads.add(MovePtr(new CreateGraphicThread( + m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions))); + + { + TestStatus thread_result = threads.run(); + if(thread_result.getCode()) + { + return thread_result; + } + } + return TestStatus::pass("Passed"); + } + +private: + ShaderModuleVector addShaderModules (const VkDevice& device) + { + const DeviceInterface& vk = m_context.getDeviceInterface(); + ShaderModuleVector shaderModules; + shaderModules.resize(m_shadersExecutions.size() + 1); + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()); ++shaderNdx) + { + ostringstream shaderName; + shaderName<<"vert_"< > (new Unique(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0))); + } + shaderModules[m_shadersExecutions.size()] = SharedPtr > (new Unique(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), (VkShaderModuleCreateFlags)0))); + return shaderModules; + } + + vector addShaderStageInfo (const ShaderModuleVector& shaderCompModules) + { + VkPipelineShaderStageCreateInfo shaderStageInfo; + vector shaderStageInfos; + shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStageInfo.pNext = DE_NULL; + shaderStageInfo.flags = (VkPipelineShaderStageCreateFlags)0; + shaderStageInfo.pName = "main"; + shaderStageInfo.pSpecializationInfo = DE_NULL; + + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()); ++shaderNdx) + { + shaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + shaderStageInfo.module = *(*shaderCompModules[shaderNdx]); + shaderStageInfos.push_back(shaderStageInfo); + + shaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + shaderStageInfo.module = *(*shaderCompModules[m_shadersExecutions.size()]); + shaderStageInfos.push_back(shaderStageInfo); + } + return shaderStageInfos; + } + + vector addPipelineInfo (VkPipelineLayout pipelineLayout, const vector& shaderStageInfos, const VkRenderPass& renderPass) + { + VkExtent3D colorImageExtent = makeExtent3D(1u, 1u, 1u); + vector pipelineInfo; + + m_vertexInputStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + m_vertexInputStateParams.pNext = DE_NULL; + m_vertexInputStateParams.flags = 0u; + m_vertexInputStateParams.vertexBindingDescriptionCount = 0u; + m_vertexInputStateParams.pVertexBindingDescriptions = DE_NULL; + m_vertexInputStateParams.vertexAttributeDescriptionCount = 0u; + m_vertexInputStateParams.pVertexAttributeDescriptions = DE_NULL; + + m_inputAssemblyStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + m_inputAssemblyStateParams.pNext = DE_NULL; + m_inputAssemblyStateParams.flags = 0u; + m_inputAssemblyStateParams.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + m_inputAssemblyStateParams.primitiveRestartEnable = VK_FALSE; + + m_viewport.x = 0.0f; + m_viewport.y = 0.0f; + m_viewport.width = (float)colorImageExtent.width; + m_viewport.height = (float)colorImageExtent.height; + m_viewport.minDepth = 0.0f; + m_viewport.maxDepth = 1.0f; + + //TODO + m_scissor.offset.x = 0; + m_scissor.offset.y = 0; + m_scissor.extent.width = colorImageExtent.width; + m_scissor.extent.height = colorImageExtent.height; + + m_viewportStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + m_viewportStateParams.pNext = DE_NULL; + m_viewportStateParams.flags = 0u; + m_viewportStateParams.viewportCount = 1u; + m_viewportStateParams.pViewports = &m_viewport; + m_viewportStateParams.scissorCount = 1u; + m_viewportStateParams.pScissors = &m_scissor; + + m_rasterStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + m_rasterStateParams.pNext = DE_NULL; + m_rasterStateParams.flags = 0u; + m_rasterStateParams.depthClampEnable = VK_FALSE; + m_rasterStateParams.rasterizerDiscardEnable = VK_FALSE; + m_rasterStateParams.polygonMode = VK_POLYGON_MODE_FILL; + m_rasterStateParams.cullMode = VK_CULL_MODE_NONE; + m_rasterStateParams.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + m_rasterStateParams.depthBiasEnable = VK_FALSE; + m_rasterStateParams.depthBiasConstantFactor = 0.0f; + m_rasterStateParams.depthBiasClamp = 0.0f; + m_rasterStateParams.depthBiasSlopeFactor = 0.0f; + m_rasterStateParams.lineWidth = 1.0f; + + m_colorBlendAttachmentState.blendEnable = VK_FALSE; + m_colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + m_colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; + m_colorBlendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; + m_colorBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + m_colorBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + m_colorBlendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; + m_colorBlendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + + m_colorBlendStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + m_colorBlendStateParams.pNext = DE_NULL; + m_colorBlendStateParams.flags = 0u; + m_colorBlendStateParams.logicOpEnable = VK_FALSE; + m_colorBlendStateParams.logicOp = VK_LOGIC_OP_COPY; + m_colorBlendStateParams.attachmentCount = 1u; + m_colorBlendStateParams.pAttachments = &m_colorBlendAttachmentState; + m_colorBlendStateParams.blendConstants[0] = 0.0f; + m_colorBlendStateParams.blendConstants[1] = 0.0f; + m_colorBlendStateParams.blendConstants[2] = 0.0f; + m_colorBlendStateParams.blendConstants[3] = 0.0f; + + m_multisampleStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + m_multisampleStateParams.pNext = DE_NULL; + m_multisampleStateParams.flags = 0u; + m_multisampleStateParams.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + m_multisampleStateParams.sampleShadingEnable = VK_FALSE; + m_multisampleStateParams.minSampleShading = 0.0f; + m_multisampleStateParams.pSampleMask = DE_NULL; + m_multisampleStateParams.alphaToCoverageEnable = VK_FALSE; + m_multisampleStateParams.alphaToOneEnable = VK_FALSE; + + m_depthStencilStateParams.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + m_depthStencilStateParams.pNext = DE_NULL; + m_depthStencilStateParams.flags = 0u; + m_depthStencilStateParams.depthTestEnable = VK_TRUE; + m_depthStencilStateParams.depthWriteEnable = VK_TRUE; + m_depthStencilStateParams.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + m_depthStencilStateParams.depthBoundsTestEnable = VK_FALSE; + m_depthStencilStateParams.stencilTestEnable = VK_FALSE; + m_depthStencilStateParams.front.failOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.front.passOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.front.depthFailOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.front.compareOp = VK_COMPARE_OP_NEVER; + m_depthStencilStateParams.front.compareMask = 0u; + m_depthStencilStateParams.front.writeMask = 0u; + m_depthStencilStateParams.front.reference = 0u; + m_depthStencilStateParams.back.failOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.back.passOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.back.depthFailOp = VK_STENCIL_OP_KEEP; + m_depthStencilStateParams.back.compareOp = VK_COMPARE_OP_NEVER; + m_depthStencilStateParams.back.compareMask = 0u; + m_depthStencilStateParams.back.writeMask = 0u; + m_depthStencilStateParams.back.reference = 0u; + m_depthStencilStateParams.minDepthBounds = 0.0f; + m_depthStencilStateParams.maxDepthBounds = 1.0f; + + VkGraphicsPipelineCreateInfo graphicsPipelineParams = + { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineCreateFlags flags; + 2u, // deUint32 stageCount; + DE_NULL, // const VkPipelineShaderStageCreateInfo* pStages; + &m_vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + &m_inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; + &m_viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; + &m_rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterState; + &m_multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + &m_depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + &m_colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; + pipelineLayout, // VkPipelineLayout layout; + renderPass, // VkRenderPass renderPass; + 0u, // deUint32 subpass; + DE_NULL, // VkPipeline basePipelineHandle; + 0, // deInt32 basePipelineIndex; + }; + for (int shaderNdx = 0; shaderNdx < static_cast(m_shadersExecutions.size()) * 2; shaderNdx+=2) + { + graphicsPipelineParams.pStages = &shaderStageInfos[shaderNdx]; + pipelineInfo.push_back(graphicsPipelineParams); + } + return pipelineInfo; + } + + const vector m_shadersExecutions; + VkPipelineVertexInputStateCreateInfo m_vertexInputStateParams; + VkPipelineInputAssemblyStateCreateInfo m_inputAssemblyStateParams; + VkViewport m_viewport; + VkRect2D m_scissor; + VkPipelineViewportStateCreateInfo m_viewportStateParams; + VkPipelineRasterizationStateCreateInfo m_rasterStateParams; + VkPipelineColorBlendAttachmentState m_colorBlendAttachmentState; + VkPipelineColorBlendStateCreateInfo m_colorBlendStateParams; + VkPipelineMultisampleStateCreateInfo m_multisampleStateParams; + VkPipelineDepthStencilStateCreateInfo m_depthStencilStateParams; +}; + +class PipelineCacheComputeTest : public TestCase +{ +public: + PipelineCacheComputeTest (TestContext& testCtx, + const string& name, + const string& description) + :TestCase (testCtx, name, description) + { + } + + void initPrograms (SourceCollections& programCollection) const + { + ostringstream buffer; + buffer << "layout(set = 0, binding = 0, std430) buffer Output\n" + << "{\n" + << " int result[];\n" + << "} sb_out;\n"; + { + ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "\n" + << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + << "\n" + << buffer.str() + << "void main (void)\n" + << "{\n" + << " highp uint ndx = gl_GlobalInvocationID.x;\n" + << " sb_out.result[ndx] = int(ndx);\n" + << "}\n"; + programCollection.glslSources.add("compute_0") << glu::ComputeSource(src.str()); + } + { + ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "\n" + << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + << "\n" + << buffer.str() + << "void main (void)\n" + << "{\n" + << " for (highp uint ndx = 0u; ndx < "< shadersExecutions; + shadersExecutions.push_back(16u); //compute_0 + shadersExecutions.push_back(1u); //compute_1 + shadersExecutions.push_back(1u); //compute_2 + return new PipelineCacheComputeTestInstance(context, shadersExecutions); + } +}; + +class PipelineCacheGraphicTest : public TestCase +{ +public: + PipelineCacheGraphicTest (TestContext& testCtx, + const string& name, + const string& description) + :TestCase (testCtx, name, description) + { + + } + + void initPrograms (SourceCollections& programCollection) const + { + ostringstream buffer; + buffer << "layout(set = 0, binding = 0, std430) buffer Output\n" + << "{\n" + << " int result[];\n" + << "} sb_out;\n"; + + // Vertex + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << buffer.str() + << "\n" + << "void main (void)\n" + << "{\n" + << " sb_out.result[gl_VertexIndex] = int(gl_VertexIndex);\n" + << "}\n"; + programCollection.glslSources.add("vert_0") << glu::VertexSource(src.str()); + } + // Vertex + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << buffer.str() + << "\n" + << "void main (void)\n" + << "{\n" + << " for (highp uint ndx = 0u; ndx < "<= 0; ndx--)\n" + << " {\n" + << " sb_out.result[uint(ndx)] = ndx;\n" + << " }\n" + << "}\n"; + programCollection.glslSources.add("vert_2") << glu::VertexSource(src.str()); + } + // Fragment + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" + << "\n" + << "layout(location = 0) out vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " o_color = vec4(1.0);\n" + << "}\n"; + programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); + } + } + + TestInstance* createInstance (Context& context) const + { + vector shadersExecutions; + shadersExecutions.push_back(16u); //vert_0 + shadersExecutions.push_back(1u); //vert_1 + shadersExecutions.push_back(1u); //vert_2 + return new PipelineCacheGraphicTestInstance(context, shadersExecutions); + } +}; + + +} // anonymous + +tcu::TestCaseGroup* createInternallySynchronizedObjects (tcu::TestContext& testCtx) +{ + de::MovePtr tests(new tcu::TestCaseGroup(testCtx, "internally_synchronized_objects", "Internally synchronized objects")); + tests->addChild(new PipelineCacheComputeTest(testCtx, "pipeline_cache_compute", "Internally synchronized object VkPipelineCache for compute pipeline is tested")); + tests->addChild(new PipelineCacheGraphicTest(testCtx, "pipeline_cache_graphics", "Internally synchronized object VkPipelineCache for graphics pipeline is tested")); + return tests.release(); +} + +} // synchronization +} // vkt \ No newline at end of file diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.hpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.hpp new file mode 100644 index 000000000..156d5e5d9 --- /dev/null +++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationInternallySynchronizedObjectsTests.hpp @@ -0,0 +1,40 @@ +#ifndef _VKTSYNCHRONIZATIONINTERNALLYSYNCHRONIZEDOBJECTSTESTS_HPP +#define _VKTSYNCHRONIZATIONINTERNALLYSYNCHRONIZEDOBJECTSTESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Synchronization internally synchronized objects tests + *//*--------------------------------------------------------------------*/ + + +#include "tcuTestCase.hpp" + +namespace vkt +{ +namespace synchronization +{ + +tcu::TestCaseGroup* createInternallySynchronizedObjects(tcu::TestContext& testCtx); + +} //synchronization +} // vkt + + +#endif // _VKTSYNCHRONIZATIONINTERNALLYSYNCHRONIZEDOBJECTSTESTS_HPP \ No newline at end of file diff --git a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTests.cpp b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTests.cpp index 8d0f6ad5f..dd5249fea 100644 --- a/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTests.cpp +++ b/external/vulkancts/modules/vulkan/synchronization/vktSynchronizationTests.cpp @@ -29,6 +29,7 @@ #include "vktSynchronizationBasicEventTests.hpp" #include "vktSynchronizationOperationSingleQueueTests.hpp" #include "vktSynchronizationOperationMultiQueueTests.hpp" +#include "vktSynchronizationInternallySynchronizedObjectsTests.hpp" #include "deUniquePtr.hpp" @@ -60,6 +61,7 @@ void createChildren (tcu::TestCaseGroup* group) group->addChild(createSmokeTests(testCtx)); group->addChild(createTestGroup (testCtx, "basic", "Basic synchronization tests", createBasicTests)); group->addChild(createTestGroup (testCtx, "op", "Synchronization of a memory-modifying operation", createOperationTests)); + group->addChild(createInternallySynchronizedObjects(testCtx)); } } // anonymous diff --git a/external/vulkancts/mustpass/1.0.1/com.drawelements.deqp.vk.xml b/external/vulkancts/mustpass/1.0.1/com.drawelements.deqp.vk.xml index 47c2a48c9..27b374998 100644 --- a/external/vulkancts/mustpass/1.0.1/com.drawelements.deqp.vk.xml +++ b/external/vulkancts/mustpass/1.0.1/com.drawelements.deqp.vk.xml @@ -343395,6 +343395,14 @@ + + + + + + + + diff --git a/external/vulkancts/mustpass/1.0.1/vk-default.txt b/external/vulkancts/mustpass/1.0.1/vk-default.txt index 4e0ff1505..5389a06a0 100644 --- a/external/vulkancts/mustpass/1.0.1/vk-default.txt +++ b/external/vulkancts/mustpass/1.0.1/vk-default.txt @@ -106609,6 +106609,8 @@ dEQP-VK.synchronization.op.multi_queue.semaphore.write_indirect_buffer_draw_inde dEQP-VK.synchronization.op.multi_queue.semaphore.write_indirect_buffer_draw_indexed_read_indirect_buffer_draw_indexed.indirect_buffer_concurrent dEQP-VK.synchronization.op.multi_queue.semaphore.write_indirect_buffer_dispatch_read_indirect_buffer_dispatch.indirect_buffer_exclusive dEQP-VK.synchronization.op.multi_queue.semaphore.write_indirect_buffer_dispatch_read_indirect_buffer_dispatch.indirect_buffer_concurrent +dEQP-VK.synchronization.internally_synchronized_objects.pipeline_cache_compute +dEQP-VK.synchronization.internally_synchronized_objects.pipeline_cache_graphics dEQP-VK.sparse_resources.buffer_sparse_binding.buffer_size_2_10 dEQP-VK.sparse_resources.buffer_sparse_binding.buffer_size_2_12 dEQP-VK.sparse_resources.buffer_sparse_binding.buffer_size_2_16 -- 2.34.1