Update Vulkan CTS to version 1.0.2.3 am: 148890e79f
[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  * 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 {
41         QueueFamilyQueuesCount() : queueCount(0u) {};
42
43         deUint32 queueCount;
44 };
45
46 static const deUint32 NO_MATCH_FOUND = ~0u;
47
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
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                         queue.queueHandle = getDeviceQueue(*m_deviceDriver, *m_logicalDevice, queue.queueFamilyIndex, queue.queueIndex);
168                 }
169         }
170 }
171
172 const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex) const
173 {
174         return m_queues.find(queueFlags)->second[queueIndex];
175 }
176
177 } // sparse
178 } // vkt