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 "vkRefUtil.hpp"
26 #include "vkQueryUtil.hpp"
27
28 using namespace vk;
29
30 namespace vkt
31 {
32 namespace sparse
33 {
34
35 struct QueueFamilyQueuesCount
36 {
QueueFamilyQueuesCountvkt::sparse::QueueFamilyQueuesCount37 QueueFamilyQueuesCount() : queueCount(0u), counter(0u) {};
38
39 deUint32 queueCount;
40 deUint32 counter;
41 };
42
SparseResourcesBaseInstance(Context & context)43 SparseResourcesBaseInstance::SparseResourcesBaseInstance (Context &context)
44 : TestInstance(context)
45 {
46 }
47
createDeviceSupportingQueues(const QueueRequirementsVec & queueRequirements)48 bool SparseResourcesBaseInstance::createDeviceSupportingQueues (const QueueRequirementsVec& queueRequirements)
49 {
50 const InstanceInterface& instance = m_context.getInstanceInterface();
51 const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
52 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
53
54 deUint32 queueFamilyPropertiesCount = 0u;
55 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
56
57 if (queueFamilyPropertiesCount == 0u)
58 {
59 return false;
60 }
61
62 std::vector<VkQueueFamilyProperties> queueFamilyProperties;
63 queueFamilyProperties.resize(queueFamilyPropertiesCount);
64
65 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, &queueFamilyProperties[0]);
66
67 typedef std::map<deUint32, QueueFamilyQueuesCount> SelectedQueuesMap;
68 typedef std::map<deUint32, std::vector<float> > QueuePrioritiesMap;
69
70 SelectedQueuesMap selectedQueueFamilies;
71 QueuePrioritiesMap queuePriorities;
72
73 for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx)
74 {
75 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx];
76 const deUint32 queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags);
77
78 if (queueFamilyIndex == NO_MATCH_FOUND)
79 {
80 return false;
81 }
82
83 selectedQueueFamilies[queueFamilyIndex].queueCount += queueRequirement.queueCount;
84 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx)
85 {
86 queuePriorities[queueFamilyIndex].push_back(1.0f);
87 }
88 }
89
90 std::vector<VkDeviceQueueCreateInfo> queueInfos;
91
92 for (SelectedQueuesMap::iterator queueFamilyIter = selectedQueueFamilies.begin(); queueFamilyIter != selectedQueueFamilies.end(); ++queueFamilyIter)
93 {
94 VkDeviceQueueCreateInfo queueInfo;
95 deMemset(&queueInfo, 0, sizeof(queueInfo));
96
97 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
98 queueInfo.pNext = DE_NULL;
99 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
100 queueInfo.queueFamilyIndex = queueFamilyIter->first;
101 queueInfo.queueCount = queueFamilyIter->second.queueCount;
102 queueInfo.pQueuePriorities = &queuePriorities[queueFamilyIter->first][0];
103
104 queueInfos.push_back(queueInfo);
105 }
106
107 VkDeviceCreateInfo deviceInfo;
108 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
109
110 VkPhysicalDeviceFeatures deviceFeatures;
111 instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
112
113 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
114 deviceInfo.pNext = DE_NULL;
115 deviceInfo.enabledExtensionCount = 0u;
116 deviceInfo.ppEnabledExtensionNames = DE_NULL;
117 deviceInfo.enabledLayerCount = 0u;
118 deviceInfo.ppEnabledLayerNames = DE_NULL;
119 deviceInfo.pEnabledFeatures = &deviceFeatures;
120 deviceInfo.queueCreateInfoCount = (deUint32)selectedQueueFamilies.size();
121 deviceInfo.pQueueCreateInfos = &queueInfos[0];
122
123 m_logicalDevice = vk::createDevice(instance, physicalDevice, &deviceInfo);
124
125 for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx)
126 {
127 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx];
128 const deUint32 queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags);
129
130 if (queueFamilyIndex == NO_MATCH_FOUND)
131 {
132 return false;
133 }
134
135 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx)
136 {
137 VkQueue queueHandle = 0;
138 deviceInterface.getDeviceQueue(*m_logicalDevice, queueFamilyIndex, selectedQueueFamilies[queueFamilyIndex].counter++, &queueHandle);
139
140 Queue queue;
141 queue.queueHandle = queueHandle;
142 queue.queueFamilyIndex = queueFamilyIndex;
143
144 m_queues[queueRequirement.queueFlags].push_back(queue);
145 }
146 }
147
148 return true;
149 }
150
getQueue(const VkQueueFlags queueFlags,const deUint32 queueIndex)151 const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex)
152 {
153 return m_queues[queueFlags][queueIndex];
154 }
155
findMatchingMemoryType(const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkMemoryRequirements & objectMemoryRequirements,const MemoryRequirement & memoryRequirement) const156 deUint32 SparseResourcesBaseInstance::findMatchingMemoryType (const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
157 const VkMemoryRequirements& objectMemoryRequirements,
158 const MemoryRequirement& memoryRequirement) const
159 {
160 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
161 {
162 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
163 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
164 {
165 return memoryTypeNdx;
166 }
167 }
168
169 return NO_MATCH_FOUND;
170 }
171
findMatchingQueueFamilyIndex(const QueueFamilyPropertiesVec & queueFamilyProperties,const VkQueueFlags queueFlags) const172 deUint32 SparseResourcesBaseInstance::findMatchingQueueFamilyIndex (const QueueFamilyPropertiesVec& queueFamilyProperties,
173 const VkQueueFlags queueFlags) const
174 {
175 for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
176 {
177 if ((queueFamilyProperties[queueNdx].queueFlags & queueFlags) == queueFlags)
178 {
179 return queueNdx;
180 }
181 }
182
183 return NO_MATCH_FOUND;
184 }
185
186 } // sparse
187 } // vkt
188