Sparse Buffer Residency Test
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / sparse_resources / vktSparseResourcesBase.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and/or associated documentation files (the
9  * "Materials"), to deal in the Materials without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Materials, and to
12  * permit persons to whom the Materials are furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice(s) and this permission notice shall be included
16  * in all copies or substantial portions of the Materials.
17  *
18  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
25  *
26  *//*!
27  * \file  vktSparseResourcesBase.cpp
28  * \brief Sparse Resources Base Instance
29  *//*--------------------------------------------------------------------*/
30
31 #include "vktSparseResourcesBase.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkQueryUtil.hpp"
34
35 using namespace vk;
36
37 namespace vkt
38 {
39 namespace sparse
40 {
41
42 struct QueueFamilyQueuesCount
43 {
44         QueueFamilyQueuesCount() : queueCount(0u), counter(0u) {};
45
46         deUint32                queueCount;
47         deUint32                counter;
48 };
49
50 SparseResourcesBaseInstance::SparseResourcesBaseInstance (Context &context) 
51         : TestInstance(context) 
52 {
53 }
54
55 bool SparseResourcesBaseInstance::createDeviceSupportingQueues (const QueueRequirementsVec&     queueRequirements)
56 {
57         const InstanceInterface&        instance                = m_context.getInstanceInterface();
58         const DeviceInterface&          deviceInterface = m_context.getDeviceInterface();
59         const VkPhysicalDevice          physicalDevice  = m_context.getPhysicalDevice();
60
61         deUint32 queueFamilyPropertiesCount = 0u;
62         instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, DE_NULL);
63
64         if (queueFamilyPropertiesCount == 0u)
65         {
66                 return false;
67         }
68
69         std::vector<VkQueueFamilyProperties> queueFamilyProperties;
70         queueFamilyProperties.resize(queueFamilyPropertiesCount);
71
72         instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, &queueFamilyProperties[0]);
73
74         typedef std::map<deUint32, QueueFamilyQueuesCount>      SelectedQueuesMap;
75         typedef std::map<deUint32, std::vector<float> >         QueuePrioritiesMap;
76
77         SelectedQueuesMap       selectedQueueFamilies;
78         QueuePrioritiesMap      queuePriorities;
79
80         for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx)
81         {
82                 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx];
83                 const deUint32                  queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags);
84
85                 if (queueFamilyIndex == NO_MATCH_FOUND)
86                 {
87                         return false;
88                 }
89
90                 selectedQueueFamilies[queueFamilyIndex].queueCount += queueRequirement.queueCount;
91                 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx)
92                 {
93                         queuePriorities[queueFamilyIndex].push_back(1.0f);
94                 }
95         }
96
97         std::vector<VkDeviceQueueCreateInfo> queueInfos;
98
99         for (SelectedQueuesMap::iterator queueFamilyIter = selectedQueueFamilies.begin(); queueFamilyIter != selectedQueueFamilies.end(); ++queueFamilyIter)
100         {
101                 VkDeviceQueueCreateInfo queueInfo;
102                 deMemset(&queueInfo, 0, sizeof(queueInfo));
103
104                 queueInfo.sType                         = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
105                 queueInfo.pNext                         = DE_NULL;
106                 queueInfo.flags                         = (VkDeviceQueueCreateFlags)0u;
107                 queueInfo.queueFamilyIndex      = queueFamilyIter->first;
108                 queueInfo.queueCount            = queueFamilyIter->second.queueCount;
109                 queueInfo.pQueuePriorities  = &queuePriorities[queueFamilyIter->first][0];
110
111                 queueInfos.push_back(queueInfo);
112         }
113
114         VkDeviceCreateInfo deviceInfo;
115         deMemset(&deviceInfo, 0, sizeof(deviceInfo));
116
117         VkPhysicalDeviceFeatures deviceFeatures;
118         instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
119
120         deviceInfo.sType                                        = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
121         deviceInfo.pNext                                        = DE_NULL;
122         deviceInfo.enabledExtensionCount        = 0u;
123         deviceInfo.ppEnabledExtensionNames      = DE_NULL;
124         deviceInfo.enabledLayerCount            = 0u;
125         deviceInfo.ppEnabledLayerNames          = DE_NULL;
126         deviceInfo.pEnabledFeatures                     = &deviceFeatures;
127         deviceInfo.queueCreateInfoCount         = (deUint32)selectedQueueFamilies.size();
128         deviceInfo.pQueueCreateInfos            = &queueInfos[0];
129
130         m_logicalDevice = vk::createDevice(instance, physicalDevice, &deviceInfo);
131
132         for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx)
133         {
134                 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx];
135                 const deUint32                  queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags);
136
137                 if (queueFamilyIndex == NO_MATCH_FOUND)
138                 {
139                         return false;
140                 }
141
142                 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx)
143                 {
144                         VkQueue queueHandle = 0;
145                         deviceInterface.getDeviceQueue(*m_logicalDevice, queueFamilyIndex, selectedQueueFamilies[queueFamilyIndex].counter++, &queueHandle);
146
147                         Queue queue;
148                         queue.queueHandle               = queueHandle;
149                         queue.queueFamilyIndex  = queueFamilyIndex;
150
151                         m_queues[queueRequirement.queueFlags].push_back(queue);
152                 }
153         }
154
155         return true;
156 }
157
158 const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex)
159 {
160         return m_queues[queueFlags][queueIndex];
161 }
162
163 deUint32 SparseResourcesBaseInstance::findMatchingMemoryType (const VkPhysicalDeviceMemoryProperties&   deviceMemoryProperties,
164                                                                                                                           const VkMemoryRequirements&                           objectMemoryRequirements,
165                                                                                                                           const MemoryRequirement&                                      memoryRequirement) const
166 {
167         for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx)
168         {
169                 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 &&
170                         memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags))
171                 {
172                         return memoryTypeNdx;
173                 }
174         }
175
176         return NO_MATCH_FOUND;
177 }
178
179 deUint32 SparseResourcesBaseInstance::findMatchingQueueFamilyIndex (const QueueFamilyPropertiesVec& queueFamilyProperties,
180                                                                                                                                         const VkQueueFlags                              queueFlags)     const
181 {
182         for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx)
183         {
184                 if ((queueFamilyProperties[queueNdx].queueFlags & queueFlags) == queueFlags)
185                 {
186                         return queueNdx;
187                 }
188         }
189
190         return NO_MATCH_FOUND;
191 }
192
193 } // sparse
194 } // vkt