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 "vktSparseResourcesTestsUtil.hpp"
     26 #include "vkMemUtil.hpp"
     27 #include "vkRefUtil.hpp"
     28 #include "vkTypeUtil.hpp"
     29 #include "vkQueryUtil.hpp"
     30 
     31 using namespace vk;
     32 
     33 namespace vkt
     34 {
     35 namespace sparse
     36 {
     37 namespace
     38 {
     39 
     40 struct QueueFamilyQueuesCount
     41 {
     42 	QueueFamilyQueuesCount() : queueCount(0u) {};
     43 
     44 	deUint32 queueCount;
     45 };
     46 
     47 deUint32 findMatchingQueueFamilyIndex (const std::vector<vk::VkQueueFamilyProperties>&	queueFamilyProperties,
     48 									   const VkQueueFlags								queueFlags,
     49 									   const deUint32									startIndex)
     50 {
     51 	for (deUint32 queueNdx = startIndex; queueNdx < queueFamilyProperties.size(); ++queueNdx)
     52 	{
     53 		if ((queueFamilyProperties[queueNdx].queueFlags & queueFlags) == queueFlags)
     54 			return queueNdx;
     55 	}
     56 
     57 	return NO_MATCH_FOUND;
     58 }
     59 
     60 } // anonymous
     61 
     62 void SparseResourcesBaseInstance::createDeviceSupportingQueues(const QueueRequirementsVec& queueRequirements)
     63 {
     64 	typedef std::map<vk::VkQueueFlags, std::vector<Queue> >		QueuesMap;
     65 	typedef std::map<deUint32, QueueFamilyQueuesCount>			SelectedQueuesMap;
     66 	typedef std::map<deUint32, std::vector<float> >				QueuePrioritiesMap;
     67 
     68 	std::vector<VkPhysicalDeviceGroupProperties>				devGroupProperties;
     69 	std::vector<const char*>									deviceExtensions;
     70 	VkDeviceGroupDeviceCreateInfo								deviceGroupInfo =
     71 	{
     72 		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR,		//stype
     73 		DE_NULL,													//pNext
     74 		0,															//physicalDeviceCount
     75 		DE_NULL														//physicalDevices
     76 	};
     77 	m_physicalDevices.push_back(m_context.getPhysicalDevice());
     78 
     79 	// If requested, create an intance with device groups
     80 	if (m_useDeviceGroups)
     81 	{
     82 		const std::vector<std::string>	requiredExtensions(1, "VK_KHR_device_group_creation");
     83 		m_deviceGroupInstance	=		createInstanceWithExtensions(m_context.getPlatformInterface(), m_context.getUsedApiVersion(), requiredExtensions);
     84 		devGroupProperties		=		enumeratePhysicalDeviceGroups(m_context.getInstanceInterface(), m_deviceGroupInstance.get());
     85 		m_numPhysicalDevices	=		devGroupProperties[m_deviceGroupIdx].physicalDeviceCount;
     86 
     87 		m_physicalDevices.clear();
     88 		for (size_t physDeviceID = 0; physDeviceID < m_numPhysicalDevices; physDeviceID++)
     89 		{
     90 			m_physicalDevices.push_back(devGroupProperties[m_deviceGroupIdx].physicalDevices[physDeviceID]);
     91 		}
     92 		if (m_numPhysicalDevices < 2)
     93 			TCU_THROW(NotSupportedError, "Sparse binding device group tests not supported with 1 physical device");
     94 
     95 		deviceGroupInfo.physicalDeviceCount = devGroupProperties[m_deviceGroupIdx].physicalDeviceCount;
     96 		deviceGroupInfo.pPhysicalDevices = devGroupProperties[m_deviceGroupIdx].physicalDevices;
     97 
     98 		if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_device_group"))
     99 			deviceExtensions.push_back("VK_KHR_device_group");
    100 	}
    101 
    102 	InstanceDriver						instance(m_context.getPlatformInterface(), m_useDeviceGroups ? m_deviceGroupInstance.get() : m_context.getInstance());
    103 	const VkPhysicalDevice				physicalDevice = getPhysicalDevice();
    104 	deUint32 queueFamilyPropertiesCount = 0u;
    105 	instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
    106 
    107 	if(queueFamilyPropertiesCount == 0u)
    108 		TCU_THROW(ResourceError, "Device reports an empty set of queue family properties");
    109 
    110 	std::vector<VkQueueFamilyProperties> queueFamilyProperties;
    111 	queueFamilyProperties.resize(queueFamilyPropertiesCount);
    112 
    113 	instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, &queueFamilyProperties[0]);
    114 
    115 	if (queueFamilyPropertiesCount == 0u)
    116 		TCU_THROW(ResourceError, "Device reports an empty set of queue family properties");
    117 
    118 	SelectedQueuesMap	selectedQueueFamilies;
    119 	QueuePrioritiesMap	queuePriorities;
    120 
    121 	for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx)
    122 	{
    123 		const QueueRequirements& queueRequirement = queueRequirements[queueReqNdx];
    124 
    125 		deUint32 queueFamilyIndex	= 0u;
    126 		deUint32 queuesFoundCount	= 0u;
    127 
    128 		do
    129 		{
    130 			queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags, queueFamilyIndex);
    131 
    132 			if (queueFamilyIndex == NO_MATCH_FOUND)
    133 				TCU_THROW(NotSupportedError, "No match found for queue requirements");
    134 
    135 			const deUint32 queuesPerFamilyCount = deMin32(queueFamilyProperties[queueFamilyIndex].queueCount, queueRequirement.queueCount - queuesFoundCount);
    136 
    137 			selectedQueueFamilies[queueFamilyIndex].queueCount = deMax32(queuesPerFamilyCount, selectedQueueFamilies[queueFamilyIndex].queueCount);
    138 
    139 			for (deUint32 queueNdx = 0; queueNdx < queuesPerFamilyCount; ++queueNdx)
    140 			{
    141 				Queue queue;
    142 				queue.queueFamilyIndex	= queueFamilyIndex;
    143 				queue.queueIndex		= queueNdx;
    144 
    145 				m_queues[queueRequirement.queueFlags].push_back(queue);
    146 			}
    147 
    148 			queuesFoundCount += queuesPerFamilyCount;
    149 
    150 			++queueFamilyIndex;
    151 		} while (queuesFoundCount < queueRequirement.queueCount);
    152 	}
    153 
    154 	std::vector<VkDeviceQueueCreateInfo> queueInfos;
    155 
    156 	for (SelectedQueuesMap::iterator queueFamilyIter = selectedQueueFamilies.begin(); queueFamilyIter != selectedQueueFamilies.end(); ++queueFamilyIter)
    157 	{
    158 		for (deUint32 queueNdx = 0; queueNdx < queueFamilyIter->second.queueCount; ++queueNdx)
    159 			queuePriorities[queueFamilyIter->first].push_back(1.0f);
    160 
    161 		const VkDeviceQueueCreateInfo queueInfo =
    162 		{
    163 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType             sType;
    164 			DE_NULL,										// const void*                 pNext;
    165 			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags    flags;
    166 			queueFamilyIter->first,							// uint32_t                    queueFamilyIndex;
    167 			queueFamilyIter->second.queueCount,				// uint32_t                    queueCount;
    168 			&queuePriorities[queueFamilyIter->first][0],	// const float*                pQueuePriorities;
    169 		};
    170 
    171 		queueInfos.push_back(queueInfo);
    172 	}
    173 
    174 	const VkPhysicalDeviceFeatures	deviceFeatures	= getPhysicalDeviceFeatures(instance, physicalDevice);
    175 	const VkDeviceCreateInfo		deviceInfo		=
    176 	{
    177 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,						// VkStructureType                    sType;
    178 		m_useDeviceGroups ? &deviceGroupInfo : DE_NULL,				// const void*                        pNext;
    179 		(VkDeviceCreateFlags)0,										// VkDeviceCreateFlags                flags;
    180 		static_cast<deUint32>(queueInfos.size())	,				// uint32_t                           queueCreateInfoCount;
    181 		&queueInfos[0],												// const VkDeviceQueueCreateInfo*     pQueueCreateInfos;
    182 		0u,															// uint32_t                           enabledLayerCount;
    183 		DE_NULL,													// const char* const*                 ppEnabledLayerNames;
    184 		deUint32(deviceExtensions.size()),							// uint32_t                           enabledExtensionCount;
    185 		deviceExtensions.size() ? &deviceExtensions[0] : DE_NULL,	// const char* const*                 ppEnabledExtensionNames;
    186 		&deviceFeatures,											// const VkPhysicalDeviceFeatures*    pEnabledFeatures;
    187 	};
    188 
    189 	m_logicalDevice = createDevice(instance, physicalDevice, &deviceInfo);
    190 	m_deviceDriver	= de::MovePtr<DeviceDriver>(new DeviceDriver(instance, *m_logicalDevice));
    191 	m_allocator		= de::MovePtr<Allocator>(new SimpleAllocator(*m_deviceDriver, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
    192 
    193 	for (QueuesMap::iterator queuesIter = m_queues.begin(); queuesIter != m_queues.end(); ++queuesIter)
    194 	{
    195 		for (deUint32 queueNdx = 0u; queueNdx < queuesIter->second.size(); ++queueNdx)
    196 		{
    197 			Queue& queue = queuesIter->second[queueNdx];
    198 
    199 			queue.queueHandle = getDeviceQueue(*m_deviceDriver, *m_logicalDevice, queue.queueFamilyIndex, queue.queueIndex);
    200 		}
    201 	}
    202 }
    203 
    204 const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex) const
    205 {
    206 	return m_queues.find(queueFlags)->second[queueIndex];
    207 }
    208 
    209 } // sparse
    210 } // vkt
    211