• 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 "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 {
QueueFamilyQueuesCountvkt::sparse::__anon56dd63ee0111::QueueFamilyQueuesCount41 	QueueFamilyQueuesCount() : queueCount(0u) {};
42 
43 	deUint32 queueCount;
44 };
45 
46 static const deUint32 NO_MATCH_FOUND = ~0u;
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 	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 
getQueue(const VkQueueFlags queueFlags,const deUint32 queueIndex) const175 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