Home | History | Annotate | Download | only in sparse_resources
      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