| /*------------------------------------------------------------------------- |
| * Vulkan CTS Framework |
| * -------------------- |
| * |
| * Copyright (c) 2015 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Vulkan platform abstraction. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vkPlatform.hpp" |
| #include "tcuFunctionLibrary.hpp" |
| #ifdef CTS_USES_VULKANSC |
| #include "vkQueryUtil.hpp" |
| #include "vkSafetyCriticalUtil.hpp" |
| #endif // CTS_USES_VULKANSC |
| |
| namespace vk |
| { |
| |
| PlatformDriver::PlatformDriver (const tcu::FunctionLibrary& library) |
| { |
| m_vk.getInstanceProcAddr = (GetInstanceProcAddrFunc)library.getFunction("vkGetInstanceProcAddr"); |
| |
| #define GET_PROC_ADDR(NAME) m_vk.getInstanceProcAddr(DE_NULL, NAME) |
| #include "vkInitPlatformFunctionPointers.inl" |
| #undef GET_PROC_ADDR |
| } |
| |
| PlatformDriver::~PlatformDriver (void) |
| { |
| } |
| |
| InstanceDriver::InstanceDriver (const PlatformInterface& platformInterface, |
| VkInstance instance) |
| { |
| loadFunctions(platformInterface, instance); |
| } |
| |
| void InstanceDriver::loadFunctions (const PlatformInterface& platformInterface, |
| VkInstance instance) |
| { |
| #define GET_PROC_ADDR(NAME) platformInterface.getInstanceProcAddr(instance, NAME) |
| #include "vkInitInstanceFunctionPointers.inl" |
| #undef GET_PROC_ADDR |
| } |
| |
| InstanceDriver::~InstanceDriver (void) |
| { |
| } |
| |
| #ifdef CTS_USES_VULKANSC |
| |
| InstanceDriverSC::InstanceDriverSC (const PlatformInterface& platformInterface, |
| VkInstance instance, |
| const tcu::CommandLine& cmdLine, |
| de::SharedPtr<vk::ResourceInterface> resourceInterface) |
| : InstanceDriver(platformInterface, instance) |
| , m_normalMode(cmdLine.isSubProcess()) |
| , m_resourceInterface(resourceInterface) |
| { |
| } |
| |
| std::pair<void**, void*> prepareDeviceGroupPatch (const VkDeviceCreateInfo* pCreateInfo) |
| { |
| struct StructureBase |
| { |
| VkStructureType sType; |
| const StructureBase* pNext; |
| }; |
| |
| const StructureBase* prev = DE_NULL; |
| const StructureBase* curr = reinterpret_cast<const StructureBase*>(pCreateInfo); |
| |
| while (curr) |
| { |
| if (curr->sType == VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO) |
| { |
| if (prev != DE_NULL) |
| return std::pair<void**, void*>((void**)&prev->pNext, (void*)curr); |
| } |
| |
| prev = curr; |
| curr = reinterpret_cast<const StructureBase*>(curr->pNext); |
| } |
| |
| return std::pair<void**, void*>(DE_NULL, DE_NULL); |
| } |
| |
| VkResult InstanceDriverSC::createDevice (VkPhysicalDevice physicalDevice, |
| const VkDeviceCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkDevice* pDevice) const |
| { |
| std::pair<void*, void*> patch = prepareDeviceGroupPatch(pCreateInfo); |
| const bool patchNeeded = patch.first != DE_NULL; |
| |
| // Structure restored from JSON does not contain valid physicalDevice. |
| // Workaround: set to delivered physicalDevice argument. |
| if (patchNeeded && m_normalMode) |
| { |
| VkDeviceGroupDeviceCreateInfo* p = (VkDeviceGroupDeviceCreateInfo*)patch.second; |
| |
| DE_ASSERT(p->physicalDeviceCount == 1); |
| |
| if (p->physicalDeviceCount == 1 && p->pPhysicalDevices[0] == DE_NULL) |
| { |
| VkPhysicalDevice* v = const_cast<VkPhysicalDevice*>(p->pPhysicalDevices); |
| v[0] = physicalDevice; |
| } |
| } |
| |
| VkResult result = InstanceDriver::createDevice(physicalDevice, pCreateInfo, pAllocator, pDevice); |
| |
| // Vulkan loader destroys pNext value when VkDeviceGroupDeviceCreateInfo is present in the chain. |
| // Workaround: Set pNext value to VkDeviceGroupDeviceCreateInfo structure back. |
| if (patchNeeded) |
| { |
| void** addr = (void**)patch.first; |
| *addr = patch.second; |
| } |
| |
| if (result == VK_SUCCESS && !m_normalMode) |
| { |
| m_resourceInterface->registerDeviceFeatures(*pDevice, pCreateInfo); |
| } |
| return result; |
| } |
| |
| #endif // CTS_USES_VULKANSC |
| |
| DeviceDriver::DeviceDriver (const PlatformInterface& platformInterface, |
| VkInstance instance, |
| VkDevice device) |
| { |
| m_vk.getDeviceProcAddr = (GetDeviceProcAddrFunc)platformInterface.getInstanceProcAddr(instance, "vkGetDeviceProcAddr"); |
| |
| #define GET_PROC_ADDR(NAME) m_vk.getDeviceProcAddr(device, NAME) |
| #include "vkInitDeviceFunctionPointers.inl" |
| #undef GET_PROC_ADDR |
| } |
| |
| DeviceDriver::~DeviceDriver (void) |
| { |
| } |
| |
| #ifdef CTS_USES_VULKANSC |
| VkResult DeviceDriver::createShaderModule (VkDevice device, |
| const VkShaderModuleCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkShaderModule* pShaderModule) const |
| { |
| // this should not be called - Vulkan SC implementation uses DeviceDriverSC instead |
| DE_UNREF(device); |
| DE_UNREF(pCreateInfo); |
| DE_UNREF(pAllocator); |
| DE_UNREF(pShaderModule); |
| TCU_THROW(InternalError, "Wrong DeviceDriver called in VulkanSC"); |
| } |
| #endif |
| |
| #ifdef CTS_USES_VULKANSC |
| |
| DeviceDriverSC::DeviceDriverSC (const PlatformInterface& platformInterface, |
| VkInstance instance, |
| VkDevice device, |
| const tcu::CommandLine& cmdLine, |
| de::SharedPtr<vk::ResourceInterface> resourceInterface, |
| const VkPhysicalDeviceVulkanSC10Properties& physicalDeviceVulkanSC10Properties, |
| const VkPhysicalDeviceProperties& physicalDeviceProperties) |
| : DeviceDriver(platformInterface, instance, device) |
| , m_normalMode(cmdLine.isSubProcess()) |
| , m_resourceInterface(resourceInterface) |
| , m_physicalDeviceVulkanSC10Properties(physicalDeviceVulkanSC10Properties) |
| , m_physicalDeviceProperties(physicalDeviceProperties) |
| , m_commandDefaultSize((VkDeviceSize)cmdLine.getCommandDefaultSize()) |
| , m_commandBufferMinimumSize( de::max((VkDeviceSize)cmdLine.getCommandDefaultSize(), (VkDeviceSize)cmdLine.getCommandBufferMinSize())) |
| , m_commandPoolMinimumSize((VkDeviceSize)cmdLine.getCommandPoolMinSize()) |
| { |
| if(!cmdLine.isSubProcess()) |
| m_falseMemory.resize(64u * 1024u * 1024u, 0u); |
| m_resourceInterface->initDevice(*this, device); |
| } |
| |
| DeviceDriverSC::~DeviceDriverSC(void) |
| { |
| } |
| |
| void DeviceDriverSC::destroyDeviceHandler (VkDevice device, |
| const VkAllocationCallbacks* pAllocator) const |
| { |
| DE_UNREF(pAllocator); |
| m_resourceInterface->unregisterDeviceFeatures(device); |
| } |
| |
| VkResult DeviceDriverSC::createDescriptorSetLayoutHandlerNorm (VkDevice device, |
| const VkDescriptorSetLayoutCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkDescriptorSetLayout* pSetLayout) const |
| { |
| DDSTAT_LOCK(); |
| VkResult result = m_vk.createDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); |
| m_resourceInterface->registerObjectHash(pSetLayout->getInternal(), calculateDescriptorSetLayoutHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createDescriptorSetLayoutHandlerStat (VkDevice device, |
| const VkDescriptorSetLayoutCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkDescriptorSetLayout* pSetLayout) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(descriptorSetLayoutRequestCount,1); |
| DDSTAT_HANDLE_CREATE(descriptorSetLayoutBindingRequestCount, pCreateInfo->bindingCount); |
| deUint32 immutableSamplersCount = 0u; |
| for (deUint32 i = 0; i < pCreateInfo->bindingCount; ++i) |
| { |
| m_resourceInterface->getStatMax().descriptorSetLayoutBindingLimit = de::max(m_resourceInterface->getStatMax().descriptorSetLayoutBindingLimit, pCreateInfo->pBindings[i].binding + 1); |
| if( ( pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ) |
| && pCreateInfo->pBindings[i].pImmutableSamplers != DE_NULL ) |
| immutableSamplersCount += pCreateInfo->pBindings[i].descriptorCount; |
| } |
| m_resourceInterface->getStatMax().maxImmutableSamplersPerDescriptorSetLayout = de::max(m_resourceInterface->getStatMax().maxImmutableSamplersPerDescriptorSetLayout, immutableSamplersCount); |
| |
| *pSetLayout = VkDescriptorSetLayout(m_resourceInterface->incResourceCounter()); |
| m_descriptorSetLayouts.insert({ *pSetLayout, *pCreateInfo }); |
| m_resourceInterface->registerObjectHash(pSetLayout->getInternal(), calculateDescriptorSetLayoutHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); |
| } |
| |
| void DeviceDriverSC::destroyDescriptorSetLayoutHandler (VkDevice device, |
| VkDescriptorSetLayout descriptorSetLayout, |
| const VkAllocationCallbacks* pAllocator) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| auto it = m_descriptorSetLayouts.find(descriptorSetLayout); |
| if (it != end(m_descriptorSetLayouts)) |
| { |
| DDSTAT_HANDLE_DESTROY(descriptorSetLayoutRequestCount, 1); |
| DDSTAT_HANDLE_DESTROY(descriptorSetLayoutBindingRequestCount, it->second.bindingCount); |
| m_descriptorSetLayouts.erase(it); |
| } |
| } |
| |
| void DeviceDriverSC::allocateDescriptorSetsHandlerStat (VkDevice device, |
| const VkDescriptorSetAllocateInfo* pAllocateInfo, |
| VkDescriptorSet* pDescriptorSets) const |
| { |
| DE_UNREF(device); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(descriptorSetRequestCount, pAllocateInfo->descriptorSetCount); |
| for (deUint32 i = 0; i < pAllocateInfo->descriptorSetCount; ++i) |
| pDescriptorSets[i] = Handle<HANDLE_TYPE_DESCRIPTOR_SET>(m_resourceInterface->incResourceCounter()); |
| for (deUint32 i = 0; i < pAllocateInfo->descriptorSetCount; ++i) |
| m_descriptorSetsInPool[pDescriptorSets[i]] = pAllocateInfo->descriptorPool; |
| } |
| |
| void DeviceDriverSC::freeDescriptorSetsHandlerStat (VkDevice device, |
| VkDescriptorPool descriptorPool, |
| uint32_t descriptorSetCount, |
| const VkDescriptorSet* pDescriptorSets) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(descriptorPool); |
| |
| DDSTAT_LOCK(); |
| for (deUint32 i = 0; i < descriptorSetCount; ++i) |
| DDSTAT_HANDLE_DESTROY_IF(pDescriptorSets[i], descriptorSetRequestCount, 1); |
| for (deUint32 i = 0; i < descriptorSetCount; ++i) |
| m_descriptorSetsInPool.erase(pDescriptorSets[i]); |
| } |
| |
| void DeviceDriverSC::resetDescriptorPoolHandlerStat (VkDevice device, |
| VkDescriptorPool descriptorPool, |
| VkDescriptorPoolResetFlags flags) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(flags); |
| |
| DDSTAT_LOCK(); |
| deUint32 removedCount = 0u; |
| for (auto it = begin(m_descriptorSetsInPool); it != end(m_descriptorSetsInPool);) |
| { |
| if (it->second.getInternal() == descriptorPool.getInternal()) |
| { |
| m_descriptorSetsInPool.erase(it++); |
| removedCount++; |
| } |
| else |
| ++it; |
| } |
| DDSTAT_HANDLE_DESTROY(descriptorSetRequestCount, removedCount); |
| } |
| |
| void DeviceDriverSC::createImageViewHandler (VkDevice device, |
| const VkImageViewCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkImageView* pView) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(imageViewRequestCount,1); |
| if (pCreateInfo->subresourceRange.layerCount > 1) |
| DDSTAT_HANDLE_CREATE(layeredImageViewRequestCount,1); |
| |
| const auto& limits = m_physicalDeviceProperties.limits; |
| |
| deUint32 levelCount = pCreateInfo->subresourceRange.levelCount; |
| if (levelCount == VK_REMAINING_MIP_LEVELS) |
| { |
| deUint32 maxDimensions = limits.maxImageDimension1D; |
| maxDimensions = de::max(maxDimensions, limits.maxImageDimension2D); |
| maxDimensions = de::max(maxDimensions, limits.maxImageDimension3D); |
| maxDimensions = de::max(maxDimensions, limits.maxImageDimensionCube); |
| levelCount = deLog2Floor32(maxDimensions) + 1; |
| } |
| |
| uint32_t layerCount = pCreateInfo->subresourceRange.layerCount; |
| if (layerCount == VK_REMAINING_ARRAY_LAYERS) |
| layerCount = limits.maxImageArrayLayers; |
| |
| m_resourceInterface->getStatMax().maxImageViewMipLevels = de::max(m_resourceInterface->getStatMax().maxImageViewMipLevels, levelCount); |
| m_resourceInterface->getStatMax().maxImageViewArrayLayers = de::max(m_resourceInterface->getStatMax().maxImageViewArrayLayers, layerCount); |
| if (pCreateInfo->subresourceRange.layerCount > 1) |
| m_resourceInterface->getStatMax().maxLayeredImageViewMipLevels = de::max(m_resourceInterface->getStatMax().maxLayeredImageViewMipLevels, levelCount); |
| |
| *pView = VkImageView(m_resourceInterface->incResourceCounter()); |
| m_imageViews.insert({ *pView, *pCreateInfo }); |
| } |
| |
| void DeviceDriverSC::destroyImageViewHandler (VkDevice device, |
| VkImageView imageView, |
| const VkAllocationCallbacks* pAllocator) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| auto it = m_imageViews.find(imageView); |
| if (it != end(m_imageViews)) |
| { |
| DDSTAT_HANDLE_DESTROY(imageViewRequestCount, 1); |
| if(it->second.subresourceRange.layerCount > 1) |
| DDSTAT_HANDLE_DESTROY(layeredImageViewRequestCount,1); |
| m_imageViews.erase(it); |
| } |
| } |
| |
| void DeviceDriverSC::createQueryPoolHandler (VkDevice device, |
| const VkQueryPoolCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkQueryPool* pQueryPool) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(queryPoolRequestCount, 1); |
| switch (pCreateInfo->queryType) |
| { |
| case VK_QUERY_TYPE_OCCLUSION: |
| m_resourceInterface->getStatMax().maxOcclusionQueriesPerPool = de::max(m_resourceInterface->getStatMax().maxOcclusionQueriesPerPool, pCreateInfo->queryCount); |
| break; |
| case VK_QUERY_TYPE_PIPELINE_STATISTICS: |
| m_resourceInterface->getStatMax().maxPipelineStatisticsQueriesPerPool = de::max(m_resourceInterface->getStatMax().maxPipelineStatisticsQueriesPerPool, pCreateInfo->queryCount); |
| break; |
| case VK_QUERY_TYPE_TIMESTAMP: |
| m_resourceInterface->getStatMax().maxTimestampQueriesPerPool = de::max(m_resourceInterface->getStatMax().maxTimestampQueriesPerPool, pCreateInfo->queryCount); |
| break; |
| default: |
| break; |
| } |
| // We don't have to track queryPool resources as we do with image views because they're not removed from memory in Vulkan SC. |
| *pQueryPool = VkQueryPool(m_resourceInterface->incResourceCounter()); |
| } |
| |
| VkResult DeviceDriverSC::createPipelineLayoutHandlerNorm (VkDevice device, |
| const VkPipelineLayoutCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipelineLayout* pPipelineLayout) const |
| { |
| DDSTAT_LOCK(); |
| VkResult result = m_vk.createPipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); |
| m_resourceInterface->registerObjectHash(pPipelineLayout->getInternal(), calculatePipelineLayoutHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createPipelineLayoutHandlerStat (VkDevice device, |
| const VkPipelineLayoutCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipelineLayout* pPipelineLayout) const |
| { |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(pipelineLayoutRequestCount, 1); |
| *pPipelineLayout = VkPipelineLayout(m_resourceInterface->incResourceCounter()); |
| m_resourceInterface->registerObjectHash(pPipelineLayout->getInternal(), calculatePipelineLayoutHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createPipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); |
| } |
| |
| VkResult DeviceDriverSC::createGraphicsPipelinesHandlerNorm (VkDevice device, |
| VkPipelineCache pipelineCache, |
| deUint32 createInfoCount, |
| const VkGraphicsPipelineCreateInfo* pCreateInfos, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipeline* pPipelines) const |
| { |
| DDSTAT_LOCK(); |
| return m_resourceInterface->createGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, m_normalMode); |
| } |
| |
| void DeviceDriverSC::createGraphicsPipelinesHandlerStat (VkDevice device, |
| VkPipelineCache pipelineCache, |
| deUint32 createInfoCount, |
| const VkGraphicsPipelineCreateInfo* pCreateInfos, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipeline* pPipelines) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pipelineCache); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(graphicsPipelineRequestCount, createInfoCount); |
| for (deUint32 i = 0; i < createInfoCount; ++i) |
| { |
| pPipelines[i] = VkPipeline(m_resourceInterface->incResourceCounter()); |
| m_graphicsPipelines.insert({ pPipelines[i], pCreateInfos[i] }); |
| } |
| |
| m_resourceInterface->createGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, m_normalMode); |
| } |
| |
| VkResult DeviceDriverSC::createComputePipelinesHandlerNorm (VkDevice device, |
| VkPipelineCache pipelineCache, |
| deUint32 createInfoCount, |
| const VkComputePipelineCreateInfo* pCreateInfos, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipeline* pPipelines) const |
| { |
| DDSTAT_LOCK(); |
| return m_resourceInterface->createComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, m_normalMode); |
| } |
| |
| void DeviceDriverSC::createComputePipelinesHandlerStat (VkDevice device, |
| VkPipelineCache pipelineCache, |
| deUint32 createInfoCount, |
| const VkComputePipelineCreateInfo* pCreateInfos, |
| const VkAllocationCallbacks* pAllocator, |
| VkPipeline* pPipelines) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pipelineCache); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(computePipelineRequestCount, createInfoCount); |
| for (deUint32 i = 0; i < createInfoCount; ++i) |
| { |
| pPipelines[i] = VkPipeline(m_resourceInterface->incResourceCounter()); |
| m_computePipelines.insert({ pPipelines[i], pCreateInfos[i] }); |
| } |
| |
| m_resourceInterface->createComputePipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, m_normalMode); |
| } |
| |
| void DeviceDriverSC::destroyPipelineHandler (VkDevice device, |
| VkPipeline pipeline, |
| const VkAllocationCallbacks* pAllocator) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| auto it = m_graphicsPipelines.find(pipeline); |
| if (it != end(m_graphicsPipelines)) |
| { |
| DDSTAT_HANDLE_DESTROY(graphicsPipelineRequestCount, 1); |
| m_graphicsPipelines.erase(it); |
| m_resourceInterface->destroyPipeline(device, pipeline, pAllocator); |
| return; |
| } |
| |
| auto it2 = m_computePipelines.find(pipeline); |
| if (it2 != end(m_computePipelines)) |
| { |
| DDSTAT_HANDLE_DESTROY(computePipelineRequestCount, 1); |
| m_resourceInterface->destroyPipeline(device, pipeline, pAllocator); |
| m_computePipelines.erase(it2); |
| } |
| } |
| |
| VkResult DeviceDriverSC::createFramebufferHandlerNorm (VkDevice device, |
| const VkFramebufferCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkFramebuffer* pFramebuffer) const |
| { |
| DDSTAT_LOCK(); |
| checkFramebufferSupport(pCreateInfo); |
| const VkResult result = m_vk.createFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer); |
| return result; |
| } |
| |
| void DeviceDriverSC::createFramebufferHandlerStat (VkDevice device, |
| const VkFramebufferCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkFramebuffer* pFramebuffer) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| checkFramebufferSupport(pCreateInfo); |
| DDSTAT_HANDLE_CREATE(framebufferRequestCount,1); |
| |
| *pFramebuffer = Handle<HANDLE_TYPE_FRAMEBUFFER>(m_resourceInterface->incResourceCounter()); |
| } |
| |
| VkResult DeviceDriverSC::createRenderPassHandlerNorm (VkDevice device, |
| const VkRenderPassCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkRenderPass* pRenderPass) const |
| { |
| DDSTAT_LOCK(); |
| |
| checkRenderPassSupport(pCreateInfo->attachmentCount, pCreateInfo->subpassCount, pCreateInfo->dependencyCount); |
| for (uint32_t subpassNdx = 0; subpassNdx < pCreateInfo->subpassCount; ++subpassNdx) |
| checkSubpassSupport(pCreateInfo->pSubpasses[subpassNdx].inputAttachmentCount, pCreateInfo->pSubpasses[subpassNdx].preserveAttachmentCount); |
| |
| VkResult result = m_vk.createRenderPass(device, pCreateInfo, pAllocator, pRenderPass); |
| m_resourceInterface->registerObjectHash(pRenderPass->getInternal(), calculateRenderPassHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createRenderPassHandlerStat (VkDevice device, |
| const VkRenderPassCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkRenderPass* pRenderPass) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| |
| checkRenderPassSupport(pCreateInfo->attachmentCount, pCreateInfo->subpassCount, pCreateInfo->dependencyCount); |
| for (uint32_t subpassNdx = 0; subpassNdx < pCreateInfo->subpassCount; ++subpassNdx) |
| checkSubpassSupport(pCreateInfo->pSubpasses[subpassNdx].inputAttachmentCount, pCreateInfo->pSubpasses[subpassNdx].preserveAttachmentCount); |
| |
| DDSTAT_HANDLE_CREATE(renderPassRequestCount, 1); |
| DDSTAT_HANDLE_CREATE(subpassDescriptionRequestCount, pCreateInfo->subpassCount); |
| DDSTAT_HANDLE_CREATE(attachmentDescriptionRequestCount, pCreateInfo->attachmentCount); |
| |
| *pRenderPass = VkRenderPass(m_resourceInterface->incResourceCounter()); |
| m_renderPasses.insert({ *pRenderPass, *pCreateInfo }); |
| m_resourceInterface->registerObjectHash(pRenderPass->getInternal(), calculateRenderPassHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createRenderPass(device, pCreateInfo, pAllocator, pRenderPass); |
| } |
| |
| VkResult DeviceDriverSC::createRenderPass2HandlerNorm (VkDevice device, |
| const VkRenderPassCreateInfo2* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkRenderPass* pRenderPass) const |
| { |
| DDSTAT_LOCK(); |
| |
| checkRenderPassSupport(pCreateInfo->attachmentCount, pCreateInfo->subpassCount, pCreateInfo->dependencyCount); |
| for (uint32_t subpassNdx = 0; subpassNdx < pCreateInfo->subpassCount; ++subpassNdx) |
| checkSubpassSupport(pCreateInfo->pSubpasses[subpassNdx].inputAttachmentCount, pCreateInfo->pSubpasses[subpassNdx].preserveAttachmentCount); |
| |
| VkResult result = m_vk.createRenderPass2(device, pCreateInfo, pAllocator, pRenderPass); |
| m_resourceInterface->registerObjectHash(pRenderPass->getInternal(), calculateRenderPass2Hash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createRenderPass2HandlerStat (VkDevice device, |
| const VkRenderPassCreateInfo2* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkRenderPass* pRenderPass) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| |
| checkRenderPassSupport(pCreateInfo->attachmentCount, pCreateInfo->subpassCount, pCreateInfo->dependencyCount); |
| for (uint32_t subpassNdx = 0; subpassNdx < pCreateInfo->subpassCount; ++subpassNdx) |
| checkSubpassSupport(pCreateInfo->pSubpasses[subpassNdx].inputAttachmentCount, pCreateInfo->pSubpasses[subpassNdx].preserveAttachmentCount); |
| |
| DDSTAT_HANDLE_CREATE(renderPassRequestCount, 1); |
| DDSTAT_HANDLE_CREATE(subpassDescriptionRequestCount, pCreateInfo->subpassCount); |
| DDSTAT_HANDLE_CREATE(attachmentDescriptionRequestCount, pCreateInfo->attachmentCount); |
| |
| *pRenderPass = VkRenderPass(m_resourceInterface->incResourceCounter()); |
| m_renderPasses2.insert({ *pRenderPass, *pCreateInfo }); |
| m_resourceInterface->registerObjectHash(pRenderPass->getInternal(), calculateRenderPass2Hash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createRenderPass2(device, pCreateInfo, pAllocator, pRenderPass); |
| } |
| |
| void DeviceDriverSC::destroyRenderPassHandler (VkDevice device, |
| VkRenderPass renderPass, |
| const VkAllocationCallbacks* pAllocator) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(pAllocator); |
| |
| DDSTAT_LOCK(); |
| auto it = m_renderPasses.find(renderPass); |
| if (it != end(m_renderPasses)) |
| { |
| DDSTAT_HANDLE_DESTROY(renderPassRequestCount, 1); |
| DDSTAT_HANDLE_DESTROY(subpassDescriptionRequestCount, it->second.subpassCount); |
| DDSTAT_HANDLE_DESTROY(attachmentDescriptionRequestCount, it->second.attachmentCount); |
| m_renderPasses.erase(it); |
| return; |
| } |
| |
| auto it2 = m_renderPasses2.find(renderPass); |
| if (it2 != end(m_renderPasses2)) |
| { |
| DDSTAT_HANDLE_DESTROY(renderPassRequestCount, 1); |
| DDSTAT_HANDLE_DESTROY(subpassDescriptionRequestCount, it2->second.subpassCount); |
| DDSTAT_HANDLE_DESTROY(attachmentDescriptionRequestCount, it2->second.attachmentCount); |
| m_renderPasses2.erase(it2); |
| } |
| } |
| |
| VkResult DeviceDriverSC::createSamplerHandlerNorm (VkDevice device, |
| const VkSamplerCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkSampler* pSampler) const |
| { |
| DDSTAT_LOCK(); |
| VkResult result = m_vk.createSampler(device, pCreateInfo, pAllocator, pSampler); |
| m_resourceInterface->registerObjectHash(pSampler->getInternal(), calculateSamplerHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createSamplerHandlerStat (VkDevice device, |
| const VkSamplerCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkSampler* pSampler) const |
| { |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(samplerRequestCount, 1); |
| *pSampler = VkSampler(m_resourceInterface->incResourceCounter()); |
| m_resourceInterface->registerObjectHash(pSampler->getInternal(), calculateSamplerHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createSampler(device, pCreateInfo, pAllocator, pSampler); |
| } |
| |
| VkResult DeviceDriverSC::createSamplerYcbcrConversionHandlerNorm (VkDevice device, |
| const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkSamplerYcbcrConversion* pYcbcrConversion) const |
| { |
| DDSTAT_LOCK(); |
| VkResult result = m_vk.createSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion); |
| m_resourceInterface->registerObjectHash(pYcbcrConversion->getInternal(), calculateSamplerYcbcrConversionHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| return result; |
| } |
| |
| void DeviceDriverSC::createSamplerYcbcrConversionHandlerStat (VkDevice device, |
| const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkSamplerYcbcrConversion* pYcbcrConversion) const |
| { |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(samplerYcbcrConversionRequestCount, 1); |
| *pYcbcrConversion = VkSamplerYcbcrConversion(m_resourceInterface->incResourceCounter()); |
| m_resourceInterface->registerObjectHash(pYcbcrConversion->getInternal(), calculateSamplerYcbcrConversionHash(*pCreateInfo, m_resourceInterface->getObjectHashes())); |
| m_resourceInterface->createSamplerYcbcrConversion(device, pCreateInfo, pAllocator, pYcbcrConversion); |
| } |
| |
| void DeviceDriverSC::getDescriptorSetLayoutSupportHandler (VkDevice device, |
| const VkDescriptorSetLayoutCreateInfo* pCreateInfo, |
| VkDescriptorSetLayoutSupport* pSupport) const |
| { |
| DE_UNREF(device); |
| |
| DDSTAT_LOCK(); |
| for (deUint32 i = 0; i < pCreateInfo->bindingCount; ++i) |
| m_resourceInterface->getStatMax().descriptorSetLayoutBindingLimit = de::max(m_resourceInterface->getStatMax().descriptorSetLayoutBindingLimit, pCreateInfo->pBindings[i].binding + 1); |
| pSupport->supported = VK_TRUE; |
| } |
| |
| VkResult DeviceDriverSC::createShaderModule (VkDevice device, |
| const VkShaderModuleCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkShaderModule* pShaderModule) const |
| { |
| DDSTAT_LOCK(); |
| return m_resourceInterface->createShaderModule(device, pCreateInfo, pAllocator, pShaderModule, m_normalMode); |
| } |
| |
| VkResult DeviceDriverSC::createCommandPoolHandlerNorm (VkDevice device, |
| const VkCommandPoolCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkCommandPool* pCommandPool) const |
| { |
| DDSTAT_LOCK(); |
| VkCommandPoolMemoryReservationCreateInfo* chainedMemoryReservation = (VkCommandPoolMemoryReservationCreateInfo*)findStructureInChain(pCreateInfo->pNext, VK_STRUCTURE_TYPE_COMMAND_POOL_MEMORY_RESERVATION_CREATE_INFO); |
| // even if we deliver our own VkCommandPoolMemoryReservationCreateInfo - we have to call ResourceInterface::getNextCommandPoolSize() and ignore its results |
| vksc_server::VulkanCommandMemoryConsumption memC = m_resourceInterface->getNextCommandPoolSize(); |
| |
| VkCommandPoolCreateInfo pCreateInfoCopy = *pCreateInfo; |
| VkCommandPoolMemoryReservationCreateInfo cpMemReservationCI; |
| if (chainedMemoryReservation == DE_NULL) |
| { |
| VkDeviceSize cmdPoolSize = de::max(memC.maxCommandPoolReservedSize, m_commandPoolMinimumSize); |
| cmdPoolSize = de::max(cmdPoolSize, memC.commandBufferCount * m_commandBufferMinimumSize); |
| cpMemReservationCI = |
| { |
| VK_STRUCTURE_TYPE_COMMAND_POOL_MEMORY_RESERVATION_CREATE_INFO, // VkStructureType sType |
| DE_NULL, // const void* pNext |
| de::max(cmdPoolSize , m_commandBufferMinimumSize), // VkDeviceSize commandPoolReservedSize |
| de::max(memC.commandBufferCount, 1u) // uint32_t commandPoolMaxCommandBuffers |
| }; |
| cpMemReservationCI.pNext = pCreateInfoCopy.pNext; |
| pCreateInfoCopy.pNext = &cpMemReservationCI; |
| } |
| |
| return m_vk.createCommandPool(device, &pCreateInfoCopy, pAllocator, pCommandPool); |
| } |
| |
| VkResult DeviceDriverSC::resetCommandPoolHandlerNorm (VkDevice device, |
| VkCommandPool commandPool, |
| VkCommandPoolResetFlags flags) const |
| { |
| return m_vk.resetCommandPool(device, commandPool, flags); |
| } |
| |
| void DeviceDriverSC::createCommandPoolHandlerStat (VkDevice device, |
| const VkCommandPoolCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkCommandPool* pCommandPool) const |
| { |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(commandPoolRequestCount, 1); |
| // Ensure that this VUID is satisfied: VUID-VkCommandPoolMemoryReservationCreateInfo-commandPoolMaxCommandBuffers-05074 |
| m_resourceInterface->getStatMax().commandBufferRequestCount = de::max(m_resourceInterface->getStatMax().commandBufferRequestCount, m_resourceInterface->getStatMax().commandPoolRequestCount); |
| // Increase maximum value of commandBufferRequestCount in case of VkCommandPoolMemoryReservationCreateInfo presence in pNext chain. |
| // ( some of the dEQP-VKSC.sc.command_pool_memory_reservation.memory_consumption.*.reserved_size tests use VkCommandPoolMemoryReservationCreateInfo without really creating command buffers and as |
| // a result - commandBufferRequestCount was too low ) |
| VkCommandPoolMemoryReservationCreateInfo* chainedMemoryReservation = (VkCommandPoolMemoryReservationCreateInfo*)findStructureInChain(pCreateInfo->pNext, VK_STRUCTURE_TYPE_COMMAND_POOL_MEMORY_RESERVATION_CREATE_INFO); |
| |
| if (chainedMemoryReservation != DE_NULL) |
| DDSTAT_HANDLE_CREATE(commandBufferRequestCount, chainedMemoryReservation->commandPoolMaxCommandBuffers); |
| else |
| DDSTAT_HANDLE_CREATE(commandBufferRequestCount, 1); |
| |
| *pCommandPool = Handle<HANDLE_TYPE_COMMAND_POOL>(m_resourceInterface->incResourceCounter()); |
| m_resourceInterface->createCommandPool(device, pCreateInfo, pAllocator, pCommandPool); |
| } |
| |
| void DeviceDriverSC::resetCommandPoolHandlerStat (VkDevice device, |
| VkCommandPool commandPool, |
| VkCommandPoolResetFlags flags) const |
| { |
| m_resourceInterface->resetCommandPool(device, commandPool, flags); |
| } |
| |
| void DeviceDriverSC::allocateCommandBuffersHandler (VkDevice device, |
| const VkCommandBufferAllocateInfo* pAllocateInfo, |
| VkCommandBuffer* pCommandBuffers) const |
| { |
| DDSTAT_LOCK(); |
| DDSTAT_HANDLE_CREATE(commandBufferRequestCount, pAllocateInfo->commandBufferCount); |
| for (deUint32 i = 0; i < pAllocateInfo->commandBufferCount; ++i) |
| pCommandBuffers[i] = (VkCommandBuffer)m_resourceInterface->incResourceCounter(); |
| m_resourceInterface->allocateCommandBuffers(device, pAllocateInfo, pCommandBuffers); |
| } |
| |
| void DeviceDriverSC::freeCommandBuffersHandler (VkDevice device, |
| VkCommandPool commandPool, |
| deUint32 commandBufferCount, |
| const VkCommandBuffer* pCommandBuffers) const |
| { |
| DE_UNREF(device); |
| DE_UNREF(commandPool); |
| DE_UNREF(commandBufferCount); |
| DE_UNREF(pCommandBuffers); |
| } |
| |
| void DeviceDriverSC::increaseCommandBufferSize (VkCommandBuffer commandBuffer, |
| VkDeviceSize commandSize) const |
| { |
| DDSTAT_LOCK(); |
| VkDeviceSize finalSize = de::max( commandSize, m_commandDefaultSize ); |
| m_resourceInterface->increaseCommandBufferSize(commandBuffer, finalSize); |
| } |
| |
| void DeviceDriverSC::checkFramebufferSupport (const VkFramebufferCreateInfo* pCreateInfo) const |
| { |
| if (m_resourceInterface->isVulkanSC()) |
| { |
| if (pCreateInfo->attachmentCount > m_physicalDeviceVulkanSC10Properties.maxFramebufferAttachments) |
| { |
| const std::string msg = "Requested framebuffer attachment count (" + de::toString(pCreateInfo->attachmentCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxFramebufferAttachments) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| } |
| } |
| |
| void DeviceDriverSC::checkRenderPassSupport (deUint32 attachmentCount, |
| deUint32 subpassCount, |
| deUint32 dependencyCount) const |
| { |
| if (m_resourceInterface->isVulkanSC()) |
| { |
| if (attachmentCount > m_physicalDeviceVulkanSC10Properties.maxFramebufferAttachments) |
| { |
| const std::string msg = "Requested render pass attachment count (" + de::toString(attachmentCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxFramebufferAttachments) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| |
| if (subpassCount > m_physicalDeviceVulkanSC10Properties.maxRenderPassSubpasses) |
| { |
| const std::string msg = "Requested subpassCount (" + de::toString(subpassCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxRenderPassSubpasses) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| |
| if (dependencyCount > m_physicalDeviceVulkanSC10Properties.maxRenderPassDependencies) |
| { |
| const std::string msg = "Requested dependencyCount (" + de::toString(dependencyCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxRenderPassDependencies) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| } |
| |
| } |
| |
| void DeviceDriverSC::checkSubpassSupport (deUint32 inputAttachmentCount, |
| deUint32 preserveAttachmentCount) const |
| { |
| if (m_resourceInterface->isVulkanSC()) |
| { |
| if (inputAttachmentCount > m_physicalDeviceVulkanSC10Properties.maxSubpassInputAttachments) |
| { |
| const std::string msg = "Requested inputAttachmentCount (" + de::toString(inputAttachmentCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxSubpassInputAttachments) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| |
| if (preserveAttachmentCount > m_physicalDeviceVulkanSC10Properties.maxSubpassPreserveAttachments) |
| { |
| const std::string msg = "Requested preserveAttachmentCount (" + de::toString(preserveAttachmentCount) |
| + ") is greater than VulkanSC limits allow (" + de::toString(m_physicalDeviceVulkanSC10Properties.maxSubpassPreserveAttachments) + ")"; |
| |
| TCU_THROW(NotSupportedError, msg); |
| } |
| } |
| } |
| |
| de::SharedPtr<ResourceInterface> DeviceDriverSC::gerResourceInterface() const |
| { |
| return m_resourceInterface; |
| } |
| |
| void DeviceDriverSC::reset() const |
| { |
| // these objects should be empty when function is invoked, but we will clear it anyway |
| m_imageViews.clear(); |
| m_renderPasses.clear(); |
| m_renderPasses2.clear(); |
| m_graphicsPipelines.clear(); |
| m_computePipelines.clear(); |
| } |
| |
| #endif // CTS_USES_VULKANSC |
| |
| #include "vkPlatformDriverImpl.inl" |
| #include "vkInstanceDriverImpl.inl" |
| #include "vkDeviceDriverImpl.inl" |
| #ifdef CTS_USES_VULKANSC |
| #include "vkDeviceDriverSCImpl.inl" |
| #endif // CTS_USES_VULKANSC |
| |
| wsi::Display* Platform::createWsiDisplay (wsi::Type) const |
| { |
| TCU_THROW(NotSupportedError, "WSI not supported"); |
| } |
| |
| bool Platform::hasDisplay (wsi::Type) const |
| { |
| return false; |
| } |
| |
| void Platform::describePlatform (std::ostream& dst) const |
| { |
| dst << "vk::Platform::describePlatform() not implemented"; |
| } |
| |
| } // vk |