blob: 987187283fbac5c263090d6c2cc1f2910936c825 [file] [log] [blame]
Alexis Hetu767b41b2018-09-26 11:25:46 -04001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nicolas Capensd689d1c2018-11-19 16:02:36 -050015#include "VkDevice.hpp"
16
Alexis Hetu767b41b2018-09-26 11:25:46 -040017#include "VkConfig.h"
18#include "VkDebug.hpp"
Alexis Hetu048974f2019-02-15 15:28:37 -050019#include "VkDescriptorSetLayout.hpp"
Alexis Hetue1f51b92019-04-23 15:34:34 -040020#include "VkFence.hpp"
Alexis Hetu9e4d0402018-10-16 15:44:12 -040021#include "VkQueue.hpp"
Alexis Hetu0da99f52019-02-27 12:54:52 -050022#include "Device/Blitter.hpp"
Nicolas Capensd689d1c2018-11-19 16:02:36 -050023
Alexis Hetue1f51b92019-04-23 15:34:34 -040024#include <chrono>
25#include <climits>
Alexis Hetu767b41b2018-09-26 11:25:46 -040026#include <new> // Must #include this to use "placement new"
27
Alexis Hetue1f51b92019-04-23 15:34:34 -040028namespace
29{
30 std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> now()
31 {
32 return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now());
33 }
34}
35
Alexis Hetu767b41b2018-09-26 11:25:46 -040036namespace vk
37{
38
39Device::Device(const Device::CreateInfo* info, void* mem)
Alexis Hetu352791e2019-05-17 16:42:34 -040040 : physicalDevice(info->pPhysicalDevice),
41 queues(reinterpret_cast<Queue*>(mem)),
42 enabledExtensionCount(info->pCreateInfo->enabledExtensionCount)
Alexis Hetu767b41b2018-09-26 11:25:46 -040043{
44 const auto* pCreateInfo = info->pCreateInfo;
45 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
46 {
47 const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
Alexis Hetue70c3512018-10-17 13:18:04 -040048 queueCount += queueCreateInfo.queueCount;
Alexis Hetu767b41b2018-09-26 11:25:46 -040049 }
50
51 uint32_t queueID = 0;
52 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
53 {
54 const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
55
56 for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
57 {
Alexis Hetue1f51b92019-04-23 15:34:34 -040058 new (&queues[queueID]) Queue();
Alexis Hetu767b41b2018-09-26 11:25:46 -040059 }
60 }
Nicolas Capensd689d1c2018-11-19 16:02:36 -050061
Alexis Hetu352791e2019-05-17 16:42:34 -040062 extensions = reinterpret_cast<ExtensionName*>(static_cast<uint8_t*>(mem) + (sizeof(Queue) * queueCount));
63 for(uint32_t i = 0; i < enabledExtensionCount; i++)
64 {
65 strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
66 }
67
Nicolas Capensd689d1c2018-11-19 16:02:36 -050068 if(pCreateInfo->enabledLayerCount)
69 {
70 // "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
Ben Clayton00424c12019-03-17 17:29:30 +000071 UNIMPLEMENTED("enabledLayerCount"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
Nicolas Capensd689d1c2018-11-19 16:02:36 -050072 }
Alexis Hetu0da99f52019-02-27 12:54:52 -050073
Alexis Hetu1a9714a2019-04-12 11:48:12 -040074 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Alexis Hetu0da99f52019-02-27 12:54:52 -050075 blitter = new sw::Blitter();
Alexis Hetu767b41b2018-09-26 11:25:46 -040076}
77
78void Device::destroy(const VkAllocationCallbacks* pAllocator)
79{
Alexis Hetuaf3c1022018-12-12 13:26:15 -050080 for(uint32_t i = 0; i < queueCount; i++)
81 {
82 queues[i].destroy();
83 }
84
Alexis Hetu767b41b2018-09-26 11:25:46 -040085 vk::deallocate(queues, pAllocator);
Alexis Hetu0da99f52019-02-27 12:54:52 -050086
87 delete blitter;
Alexis Hetu767b41b2018-09-26 11:25:46 -040088}
89
90size_t Device::ComputeRequiredAllocationSize(const Device::CreateInfo* info)
91{
92 uint32_t queueCount = 0;
93 for(uint32_t i = 0; i < info->pCreateInfo->queueCreateInfoCount; i++)
94 {
95 queueCount += info->pCreateInfo->pQueueCreateInfos[i].queueCount;
96 }
97
Alexis Hetu352791e2019-05-17 16:42:34 -040098 return (sizeof(Queue) * queueCount) + (info->pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
99}
100
101bool Device::hasExtension(const char* extensionName) const
102{
103 for(uint32_t i = 0; i < enabledExtensionCount; i++)
104 {
105 if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
106 {
107 return true;
108 }
109 }
110 return false;
Alexis Hetu767b41b2018-09-26 11:25:46 -0400111}
112
113VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
114{
115 ASSERT(queueFamilyIndex == 0);
116
117 return queues[queueIndex];
118}
119
Alexis Hetue1f51b92019-04-23 15:34:34 -0400120VkResult Device::waitForFences(uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
Alexis Hetuc4bd9df2018-12-07 11:28:40 -0500121{
Alexis Hetue1f51b92019-04-23 15:34:34 -0400122 const time_point start = now();
123 const uint64_t max_timeout = (LLONG_MAX - start.time_since_epoch().count());
124 bool infiniteTimeout = (timeout > max_timeout);
125 const time_point end_ns = start + std::chrono::nanoseconds(std::min(max_timeout, timeout));
126 if(waitAll) // All fences must be signaled
127 {
128 for(uint32_t i = 0; i < fenceCount; i++)
129 {
130 if(timeout == 0)
131 {
132 if(Cast(pFences[i])->getStatus() != VK_SUCCESS) // At least one fence is not signaled
133 {
134 return VK_TIMEOUT;
135 }
136 }
137 else if(infiniteTimeout)
138 {
139 if(Cast(pFences[i])->wait() != VK_SUCCESS) // At least one fence is not signaled
140 {
141 return VK_TIMEOUT;
142 }
143 }
144 else
145 {
146 if(Cast(pFences[i])->waitUntil(end_ns) != VK_SUCCESS) // At least one fence is not signaled
147 {
148 return VK_TIMEOUT;
149 }
150 }
151 }
152
153 return VK_SUCCESS;
154 }
155 else // At least one fence must be signaled
156 {
157 // Start by quickly checking the status of all fences, as only one is required
158 for(uint32_t i = 0; i < fenceCount; i++)
159 {
160 if(Cast(pFences[i])->getStatus() == VK_SUCCESS) // At least one fence is signaled
161 {
162 return VK_SUCCESS;
163 }
164 }
165
166 if(timeout > 0)
167 {
168 for(uint32_t i = 0; i < fenceCount; i++)
169 {
170 if(infiniteTimeout)
171 {
172 if(Cast(pFences[i])->wait() == VK_SUCCESS) // At least one fence is signaled
173 {
174 return VK_SUCCESS;
175 }
176 }
177 else
178 {
179 if(Cast(pFences[i])->waitUntil(end_ns) == VK_SUCCESS) // At least one fence is signaled
180 {
181 return VK_SUCCESS;
182 }
183 }
184 }
185 }
186
187 return VK_TIMEOUT;
188 }
Alexis Hetuc4bd9df2018-12-07 11:28:40 -0500189}
190
Alexis Hetue1f51b92019-04-23 15:34:34 -0400191VkResult Device::waitIdle()
Ben Clayton00424c12019-03-17 17:29:30 +0000192{
193 for(uint32_t i = 0; i < queueCount; i++)
194 {
195 queues[i].waitIdle();
196 }
Alexis Hetue1f51b92019-04-23 15:34:34 -0400197
198 return VK_SUCCESS;
Alexis Hetucda0cf92019-01-24 15:48:55 -0500199}
200
Alexis Hetu9e4d0402018-10-16 15:44:12 -0400201void Device::getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
202 VkDescriptorSetLayoutSupport* pSupport) const
203{
204 // Mark everything as unsupported
205 pSupport->supported = VK_FALSE;
206}
207
Alexis Hetu048974f2019-02-15 15:28:37 -0500208void Device::updateDescriptorSets(uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites,
209 uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies)
210{
211 for(uint32_t i = 0; i < descriptorWriteCount; i++)
212 {
213 DescriptorSetLayout::WriteDescriptorSet(pDescriptorWrites[i]);
214 }
215
216 for(uint32_t i = 0; i < descriptorCopyCount; i++)
217 {
218 DescriptorSetLayout::CopyDescriptorSet(pDescriptorCopies[i]);
219 }
220}
221
Alexis Hetu767b41b2018-09-26 11:25:46 -0400222} // namespace vk