blob: aa86cc630a1b64b3c84b016bdc2a2f5ced79708c [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
Nicolas Capens0c736802019-05-27 12:53:31 -040039Device::Device(const VkDeviceCreateInfo* pCreateInfo, void* mem, PhysicalDevice *physicalDevice)
40 : physicalDevice(physicalDevice),
Alexis Hetu352791e2019-05-17 16:42:34 -040041 queues(reinterpret_cast<Queue*>(mem)),
Nicolas Capens0c736802019-05-27 12:53:31 -040042 enabledExtensionCount(pCreateInfo->enabledExtensionCount)
Alexis Hetu767b41b2018-09-26 11:25:46 -040043{
Alexis Hetu767b41b2018-09-26 11:25:46 -040044 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
45 {
46 const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
Alexis Hetue70c3512018-10-17 13:18:04 -040047 queueCount += queueCreateInfo.queueCount;
Alexis Hetu767b41b2018-09-26 11:25:46 -040048 }
49
50 uint32_t queueID = 0;
51 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
52 {
53 const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
54
55 for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
56 {
Alexis Hetue1f51b92019-04-23 15:34:34 -040057 new (&queues[queueID]) Queue();
Alexis Hetu767b41b2018-09-26 11:25:46 -040058 }
59 }
Nicolas Capensd689d1c2018-11-19 16:02:36 -050060
Alexis Hetu352791e2019-05-17 16:42:34 -040061 extensions = reinterpret_cast<ExtensionName*>(static_cast<uint8_t*>(mem) + (sizeof(Queue) * queueCount));
62 for(uint32_t i = 0; i < enabledExtensionCount; i++)
63 {
64 strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
65 }
66
Nicolas Capensd689d1c2018-11-19 16:02:36 -050067 if(pCreateInfo->enabledLayerCount)
68 {
69 // "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
Ben Clayton00424c12019-03-17 17:29:30 +000070 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 -050071 }
Alexis Hetu0da99f52019-02-27 12:54:52 -050072
Alexis Hetu1a9714a2019-04-12 11:48:12 -040073 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Alexis Hetu0da99f52019-02-27 12:54:52 -050074 blitter = new sw::Blitter();
Alexis Hetu767b41b2018-09-26 11:25:46 -040075}
76
77void Device::destroy(const VkAllocationCallbacks* pAllocator)
78{
Alexis Hetuaf3c1022018-12-12 13:26:15 -050079 for(uint32_t i = 0; i < queueCount; i++)
80 {
Ben Clayton7e0a0362019-05-20 11:32:35 +010081 queues[i].~Queue();
Alexis Hetuaf3c1022018-12-12 13:26:15 -050082 }
83
Alexis Hetu767b41b2018-09-26 11:25:46 -040084 vk::deallocate(queues, pAllocator);
Alexis Hetu0da99f52019-02-27 12:54:52 -050085
86 delete blitter;
Alexis Hetu767b41b2018-09-26 11:25:46 -040087}
88
Nicolas Capens0c736802019-05-27 12:53:31 -040089size_t Device::ComputeRequiredAllocationSize(const VkDeviceCreateInfo* pCreateInfo)
Alexis Hetu767b41b2018-09-26 11:25:46 -040090{
91 uint32_t queueCount = 0;
Nicolas Capens0c736802019-05-27 12:53:31 -040092 for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
Alexis Hetu767b41b2018-09-26 11:25:46 -040093 {
Nicolas Capens0c736802019-05-27 12:53:31 -040094 queueCount += pCreateInfo->pQueueCreateInfos[i].queueCount;
Alexis Hetu767b41b2018-09-26 11:25:46 -040095 }
96
Nicolas Capens0c736802019-05-27 12:53:31 -040097 return (sizeof(Queue) * queueCount) + (pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
Alexis Hetu352791e2019-05-17 16:42:34 -040098}
99
100bool Device::hasExtension(const char* extensionName) const
101{
102 for(uint32_t i = 0; i < enabledExtensionCount; i++)
103 {
104 if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
105 {
106 return true;
107 }
108 }
109 return false;
Alexis Hetu767b41b2018-09-26 11:25:46 -0400110}
111
112VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
113{
114 ASSERT(queueFamilyIndex == 0);
115
116 return queues[queueIndex];
117}
118
Alexis Hetue1f51b92019-04-23 15:34:34 -0400119VkResult Device::waitForFences(uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout)
Alexis Hetuc4bd9df2018-12-07 11:28:40 -0500120{
Ben Clayton6779e5e2019-05-20 11:07:58 +0100121 using time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;
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 {
Ben Clayton6779e5e2019-05-20 11:07:58 +0100146 if(Cast(pFences[i])->wait(end_ns) != VK_SUCCESS) // At least one fence is not signaled
Alexis Hetue1f51b92019-04-23 15:34:34 -0400147 {
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 {
Ben Clayton6779e5e2019-05-20 11:07:58 +0100179 if(Cast(pFences[i])->wait(end_ns) == VK_SUCCESS) // At least one fence is signaled
Alexis Hetue1f51b92019-04-23 15:34:34 -0400180 {
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