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