1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file vktSparseResourcesBase.cpp 21 * \brief Sparse Resources Base Instance 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktSparseResourcesBase.hpp" 25 #include "vkMemUtil.hpp" 26 #include "vkRefUtil.hpp" 27 #include "vkTypeUtil.hpp" 28 #include "vkQueryUtil.hpp" 29 30 using namespace vk; 31 32 namespace vkt 33 { 34 namespace sparse 35 { 36 namespace 37 { 38 39 struct QueueFamilyQueuesCount 40 { 41 QueueFamilyQueuesCount() : queueCount(0u) {}; 42 43 deUint32 queueCount; 44 }; 45 46 static const deUint32 NO_MATCH_FOUND = ~0u; 47 48 deUint32 findMatchingQueueFamilyIndex (const std::vector<vk::VkQueueFamilyProperties>& queueFamilyProperties, 49 const VkQueueFlags queueFlags, 50 const deUint32 startIndex) 51 { 52 for (deUint32 queueNdx = startIndex; queueNdx < queueFamilyProperties.size(); ++queueNdx) 53 { 54 if ((queueFamilyProperties[queueNdx].queueFlags & queueFlags) == queueFlags) 55 return queueNdx; 56 } 57 58 return NO_MATCH_FOUND; 59 } 60 61 } // anonymous 62 63 void SparseResourcesBaseInstance::createDeviceSupportingQueues(const QueueRequirementsVec& queueRequirements) 64 { 65 typedef std::map<vk::VkQueueFlags, std::vector<Queue> > QueuesMap; 66 typedef std::map<deUint32, QueueFamilyQueuesCount> SelectedQueuesMap; 67 typedef std::map<deUint32, std::vector<float> > QueuePrioritiesMap; 68 69 const InstanceInterface& instance = m_context.getInstanceInterface(); 70 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 71 72 deUint32 queueFamilyPropertiesCount = 0u; 73 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, DE_NULL); 74 75 if(queueFamilyPropertiesCount == 0u) 76 TCU_THROW(ResourceError, "Device reports an empty set of queue family properties"); 77 78 std::vector<VkQueueFamilyProperties> queueFamilyProperties; 79 queueFamilyProperties.resize(queueFamilyPropertiesCount); 80 81 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, &queueFamilyProperties[0]); 82 83 if (queueFamilyPropertiesCount == 0u) 84 TCU_THROW(ResourceError, "Device reports an empty set of queue family properties"); 85 86 SelectedQueuesMap selectedQueueFamilies; 87 QueuePrioritiesMap queuePriorities; 88 89 for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx) 90 { 91 const QueueRequirements& queueRequirement = queueRequirements[queueReqNdx]; 92 93 deUint32 queueFamilyIndex = 0u; 94 deUint32 queuesFoundCount = 0u; 95 96 do 97 { 98 queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags, queueFamilyIndex); 99 100 if (queueFamilyIndex == NO_MATCH_FOUND) 101 TCU_THROW(NotSupportedError, "No match found for queue requirements"); 102 103 const deUint32 queuesPerFamilyCount = deMin32(queueFamilyProperties[queueFamilyIndex].queueCount, queueRequirement.queueCount - queuesFoundCount); 104 105 selectedQueueFamilies[queueFamilyIndex].queueCount = deMax32(queuesPerFamilyCount, selectedQueueFamilies[queueFamilyIndex].queueCount); 106 107 for (deUint32 queueNdx = 0; queueNdx < queuesPerFamilyCount; ++queueNdx) 108 { 109 Queue queue; 110 queue.queueFamilyIndex = queueFamilyIndex; 111 queue.queueIndex = queueNdx; 112 113 m_queues[queueRequirement.queueFlags].push_back(queue); 114 } 115 116 queuesFoundCount += queuesPerFamilyCount; 117 118 ++queueFamilyIndex; 119 } while (queuesFoundCount < queueRequirement.queueCount); 120 } 121 122 std::vector<VkDeviceQueueCreateInfo> queueInfos; 123 124 for (SelectedQueuesMap::iterator queueFamilyIter = selectedQueueFamilies.begin(); queueFamilyIter != selectedQueueFamilies.end(); ++queueFamilyIter) 125 { 126 for (deUint32 queueNdx = 0; queueNdx < queueFamilyIter->second.queueCount; ++queueNdx) 127 queuePriorities[queueFamilyIter->first].push_back(1.0f); 128 129 const VkDeviceQueueCreateInfo queueInfo = 130 { 131 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType; 132 DE_NULL, // const void* pNext; 133 (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags; 134 queueFamilyIter->first, // uint32_t queueFamilyIndex; 135 queueFamilyIter->second.queueCount, // uint32_t queueCount; 136 &queuePriorities[queueFamilyIter->first][0], // const float* pQueuePriorities; 137 }; 138 139 queueInfos.push_back(queueInfo); 140 } 141 142 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 143 const VkDeviceCreateInfo deviceInfo = 144 { 145 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType; 146 DE_NULL, // const void* pNext; 147 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags; 148 static_cast<deUint32>(queueInfos.size()), // uint32_t queueCreateInfoCount; 149 &queueInfos[0], // const VkDeviceQueueCreateInfo* pQueueCreateInfos; 150 0u, // uint32_t enabledLayerCount; 151 DE_NULL, // const char* const* ppEnabledLayerNames; 152 0u, // uint32_t enabledExtensionCount; 153 DE_NULL, // const char* const* ppEnabledExtensionNames; 154 &deviceFeatures, // const VkPhysicalDeviceFeatures* pEnabledFeatures; 155 }; 156 157 m_logicalDevice = createDevice(instance, physicalDevice, &deviceInfo); 158 m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(instance, *m_logicalDevice)); 159 m_allocator = de::MovePtr<Allocator>(new SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice))); 160 161 for (QueuesMap::iterator queuesIter = m_queues.begin(); queuesIter != m_queues.end(); ++queuesIter) 162 { 163 for (deUint32 queueNdx = 0u; queueNdx < queuesIter->second.size(); ++queueNdx) 164 { 165 Queue& queue = queuesIter->second[queueNdx]; 166 167 VkQueue queueHandle = 0; 168 m_deviceDriver->getDeviceQueue(*m_logicalDevice, queue.queueFamilyIndex, queue.queueIndex, &queueHandle); 169 170 queue.queueHandle = queueHandle; 171 } 172 } 173 } 174 175 const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex) const 176 { 177 return m_queues.find(queueFlags)->second[queueIndex]; 178 } 179 180 } // sparse 181 } // vkt 182