• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
15 #include "VkDevice.hpp"
16 
17 #include "VkConfig.hpp"
18 #include "VkDescriptorSetLayout.hpp"
19 #include "VkFence.hpp"
20 #include "VkQueue.hpp"
21 #include "VkSemaphore.hpp"
22 #include "VkTimelineSemaphore.hpp"
23 #include "Debug/Context.hpp"
24 #include "Debug/Server.hpp"
25 #include "Device/Blitter.hpp"
26 #include "System/Debug.hpp"
27 
28 #include <chrono>
29 #include <climits>
30 #include <new>  // Must #include this to use "placement new"
31 
32 namespace {
33 
34 using time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;
35 
now()36 time_point now()
37 {
38 	return std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now());
39 }
40 
getEndTimePoint(uint64_t timeout,bool & infiniteTimeout)41 const time_point getEndTimePoint(uint64_t timeout, bool &infiniteTimeout)
42 {
43 	const time_point start = now();
44 	const uint64_t max_timeout = (LLONG_MAX - start.time_since_epoch().count());
45 	infiniteTimeout = (timeout > max_timeout);
46 	return start + std::chrono::nanoseconds(std::min(max_timeout, timeout));
47 }
48 
49 }  // anonymous namespace
50 
51 namespace vk {
52 
updateSnapshot()53 void Device::SamplingRoutineCache::updateSnapshot()
54 {
55 	marl::lock lock(mutex);
56 
57 	if(snapshotNeedsUpdate)
58 	{
59 		snapshot.clear();
60 
61 		for(auto it : cache)
62 		{
63 			snapshot[it.key()] = it.data();
64 		}
65 
66 		snapshotNeedsUpdate = false;
67 	}
68 }
69 
~SamplerIndexer()70 Device::SamplerIndexer::~SamplerIndexer()
71 {
72 	ASSERT(map.empty());
73 }
74 
index(const SamplerState & samplerState)75 uint32_t Device::SamplerIndexer::index(const SamplerState &samplerState)
76 {
77 	marl::lock lock(mutex);
78 
79 	auto it = map.find(samplerState);
80 
81 	if(it != map.end())
82 	{
83 		it->second.count++;
84 		return it->second.id;
85 	}
86 
87 	nextID++;
88 
89 	map.emplace(samplerState, Identifier{ nextID, 1 });
90 
91 	return nextID;
92 }
93 
remove(const SamplerState & samplerState)94 void Device::SamplerIndexer::remove(const SamplerState &samplerState)
95 {
96 	marl::lock lock(mutex);
97 
98 	auto it = map.find(samplerState);
99 	ASSERT(it != map.end());
100 
101 	auto count = --it->second.count;
102 	if(count == 0)
103 	{
104 		map.erase(it);
105 	}
106 }
107 
Device(const VkDeviceCreateInfo * pCreateInfo,void * mem,PhysicalDevice * physicalDevice,const VkPhysicalDeviceFeatures * enabledFeatures,const std::shared_ptr<marl::Scheduler> & scheduler)108 Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice *physicalDevice, const VkPhysicalDeviceFeatures *enabledFeatures, const std::shared_ptr<marl::Scheduler> &scheduler)
109     : physicalDevice(physicalDevice)
110     , queues(reinterpret_cast<Queue *>(mem))
111     , enabledExtensionCount(pCreateInfo->enabledExtensionCount)
112     , enabledFeatures(enabledFeatures ? *enabledFeatures : VkPhysicalDeviceFeatures{})
113     ,  // "Setting pEnabledFeatures to NULL and not including a VkPhysicalDeviceFeatures2 in the pNext member of VkDeviceCreateInfo is equivalent to setting all members of the structure to VK_FALSE."
114     scheduler(scheduler)
115 {
116 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
117 	{
118 		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
119 		queueCount += queueCreateInfo.queueCount;
120 	}
121 
122 	uint32_t queueID = 0;
123 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
124 	{
125 		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
126 
127 		for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
128 		{
129 			new(&queues[queueID]) Queue(this, scheduler.get());
130 		}
131 	}
132 
133 	extensions = reinterpret_cast<ExtensionName *>(static_cast<uint8_t *>(mem) + (sizeof(Queue) * queueCount));
134 	for(uint32_t i = 0; i < enabledExtensionCount; i++)
135 	{
136 		strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
137 	}
138 
139 	if(pCreateInfo->enabledLayerCount)
140 	{
141 		// "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
142 		UNSUPPORTED("enabledLayerCount");
143 	}
144 
145 	// FIXME (b/119409619): use an allocator here so we can control all memory allocations
146 	blitter.reset(new sw::Blitter());
147 	samplingRoutineCache.reset(new SamplingRoutineCache());
148 	samplerIndexer.reset(new SamplerIndexer());
149 
150 #ifdef ENABLE_VK_DEBUGGER
151 	static auto port = getenv("VK_DEBUGGER_PORT");
152 	if(port)
153 	{
154 		// Construct the debugger context and server - this may block for a
155 		// debugger connection, allowing breakpoints to be set before they're
156 		// executed.
157 		debugger.context = vk::dbg::Context::create();
158 		debugger.server = vk::dbg::Server::create(debugger.context, atoi(port));
159 	}
160 #endif  // ENABLE_VK_DEBUGGER
161 
162 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
163 	const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
164 	while(extensionCreateInfo)
165 	{
166 		if(extensionCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT)
167 		{
168 			auto deviceMemoryReportCreateInfo = reinterpret_cast<const VkDeviceDeviceMemoryReportCreateInfoEXT *>(pCreateInfo->pNext);
169 			if(deviceMemoryReportCreateInfo->pfnUserCallback != nullptr)
170 			{
171 				deviceMemoryReportCallbacks.emplace_back(deviceMemoryReportCreateInfo->pfnUserCallback, deviceMemoryReportCreateInfo->pUserData);
172 			}
173 		}
174 		extensionCreateInfo = extensionCreateInfo->pNext;
175 	}
176 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
177 }
178 
destroy(const VkAllocationCallbacks * pAllocator)179 void Device::destroy(const VkAllocationCallbacks *pAllocator)
180 {
181 	for(uint32_t i = 0; i < queueCount; i++)
182 	{
183 		queues[i].~Queue();
184 	}
185 
186 	vk::deallocate(queues, pAllocator);
187 }
188 
ComputeRequiredAllocationSize(const VkDeviceCreateInfo * pCreateInfo)189 size_t Device::ComputeRequiredAllocationSize(const VkDeviceCreateInfo *pCreateInfo)
190 {
191 	uint32_t queueCount = 0;
192 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
193 	{
194 		queueCount += pCreateInfo->pQueueCreateInfos[i].queueCount;
195 	}
196 
197 	return (sizeof(Queue) * queueCount) + (pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
198 }
199 
hasExtension(const char * extensionName) const200 bool Device::hasExtension(const char *extensionName) const
201 {
202 	for(uint32_t i = 0; i < enabledExtensionCount; i++)
203 	{
204 		if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
205 		{
206 			return true;
207 		}
208 	}
209 	return false;
210 }
211 
getQueue(uint32_t queueFamilyIndex,uint32_t queueIndex) const212 VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
213 {
214 	ASSERT(queueFamilyIndex == 0);
215 
216 	return queues[queueIndex];
217 }
218 
waitForFences(uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)219 VkResult Device::waitForFences(uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout)
220 {
221 	bool infiniteTimeout = false;
222 	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);
223 
224 	if(waitAll != VK_FALSE)  // All fences must be signaled
225 	{
226 		for(uint32_t i = 0; i < fenceCount; i++)
227 		{
228 			if(timeout == 0)
229 			{
230 				if(Cast(pFences[i])->getStatus() != VK_SUCCESS)  // At least one fence is not signaled
231 				{
232 					return VK_TIMEOUT;
233 				}
234 			}
235 			else if(infiniteTimeout)
236 			{
237 				if(Cast(pFences[i])->wait() != VK_SUCCESS)  // At least one fence is not signaled
238 				{
239 					return VK_TIMEOUT;
240 				}
241 			}
242 			else
243 			{
244 				if(Cast(pFences[i])->wait(end_ns) != VK_SUCCESS)  // At least one fence is not signaled
245 				{
246 					return VK_TIMEOUT;
247 				}
248 			}
249 		}
250 
251 		return VK_SUCCESS;
252 	}
253 	else  // At least one fence must be signaled
254 	{
255 		marl::containers::vector<marl::Event, 8> events;
256 		for(uint32_t i = 0; i < fenceCount; i++)
257 		{
258 			events.push_back(Cast(pFences[i])->getCountedEvent()->event());
259 		}
260 
261 		auto any = marl::Event::any(events.begin(), events.end());
262 
263 		if(timeout == 0)
264 		{
265 			return any.isSignalled() ? VK_SUCCESS : VK_TIMEOUT;
266 		}
267 		else if(infiniteTimeout)
268 		{
269 			any.wait();
270 			return VK_SUCCESS;
271 		}
272 		else
273 		{
274 			return any.wait_until(end_ns) ? VK_SUCCESS : VK_TIMEOUT;
275 		}
276 	}
277 }
278 
waitForSemaphores(const VkSemaphoreWaitInfo * pWaitInfo,uint64_t timeout)279 VkResult Device::waitForSemaphores(const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout)
280 {
281 	bool infiniteTimeout = false;
282 	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);
283 
284 	if(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT)
285 	{
286 		TimelineSemaphore any = TimelineSemaphore();
287 
288 		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
289 		{
290 			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
291 			uint64_t waitValue = pWaitInfo->pValues[i];
292 
293 			if(semaphore->getCounterValue() == waitValue)
294 			{
295 				return VK_SUCCESS;
296 			}
297 
298 			semaphore->addDependent(any, waitValue);
299 		}
300 
301 		if(infiniteTimeout)
302 		{
303 			any.wait(1ull);
304 			return VK_SUCCESS;
305 		}
306 		else
307 		{
308 			if(any.wait(1, end_ns) == VK_SUCCESS)
309 			{
310 				return VK_SUCCESS;
311 			}
312 		}
313 
314 		return VK_TIMEOUT;
315 	}
316 	else
317 	{
318 		ASSERT(pWaitInfo->flags == 0);
319 		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
320 		{
321 			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
322 			uint64_t value = pWaitInfo->pValues[i];
323 			if(infiniteTimeout)
324 			{
325 				semaphore->wait(value);
326 			}
327 			else if(semaphore->wait(pWaitInfo->pValues[i], end_ns) != VK_SUCCESS)
328 			{
329 				return VK_TIMEOUT;
330 			}
331 		}
332 		return VK_SUCCESS;
333 	}
334 }
335 
waitIdle()336 VkResult Device::waitIdle()
337 {
338 	for(uint32_t i = 0; i < queueCount; i++)
339 	{
340 		queues[i].waitIdle();
341 	}
342 
343 	return VK_SUCCESS;
344 }
345 
getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo * pCreateInfo,VkDescriptorSetLayoutSupport * pSupport) const346 void Device::getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
347                                            VkDescriptorSetLayoutSupport *pSupport) const
348 {
349 	// From Vulkan Spec 13.2.1 Descriptor Set Layout, in description of vkGetDescriptorSetLayoutSupport:
350 	// "This command does not consider other limits such as maxPerStageDescriptor*, and so a descriptor
351 	// set layout that is supported according to this command must still satisfy the pipeline layout limits
352 	// such as maxPerStageDescriptor* in order to be used in a pipeline layout."
353 
354 	// We have no "strange" limitations to enforce beyond the device limits, so we can safely always claim support.
355 	pSupport->supported = VK_TRUE;
356 }
357 
updateDescriptorSets(uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)358 void Device::updateDescriptorSets(uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
359                                   uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies)
360 {
361 	for(uint32_t i = 0; i < descriptorWriteCount; i++)
362 	{
363 		DescriptorSetLayout::WriteDescriptorSet(this, pDescriptorWrites[i]);
364 	}
365 
366 	for(uint32_t i = 0; i < descriptorCopyCount; i++)
367 	{
368 		DescriptorSetLayout::CopyDescriptorSet(pDescriptorCopies[i]);
369 	}
370 }
371 
getRequirements(VkMemoryDedicatedRequirements * requirements) const372 void Device::getRequirements(VkMemoryDedicatedRequirements *requirements) const
373 {
374 	requirements->prefersDedicatedAllocation = VK_FALSE;
375 	requirements->requiresDedicatedAllocation = VK_FALSE;
376 }
377 
getSamplingRoutineCache() const378 Device::SamplingRoutineCache *Device::getSamplingRoutineCache() const
379 {
380 	return samplingRoutineCache.get();
381 }
382 
updateSamplingRoutineSnapshotCache()383 void Device::updateSamplingRoutineSnapshotCache()
384 {
385 	samplingRoutineCache->updateSnapshot();
386 }
387 
indexSampler(const SamplerState & samplerState)388 uint32_t Device::indexSampler(const SamplerState &samplerState)
389 {
390 	return samplerIndexer->index(samplerState);
391 }
392 
removeSampler(const SamplerState & samplerState)393 void Device::removeSampler(const SamplerState &samplerState)
394 {
395 	samplerIndexer->remove(samplerState);
396 }
397 
setDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT * pNameInfo)398 VkResult Device::setDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
399 {
400 	// Optionally maps user-friendly name to an object
401 	return VK_SUCCESS;
402 }
403 
setDebugUtilsObjectTag(const VkDebugUtilsObjectTagInfoEXT * pTagInfo)404 VkResult Device::setDebugUtilsObjectTag(const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
405 {
406 	// Optionally attach arbitrary data to an object
407 	return VK_SUCCESS;
408 }
409 
registerImageView(ImageView * imageView)410 void Device::registerImageView(ImageView *imageView)
411 {
412 	if(imageView != nullptr)
413 	{
414 		marl::lock lock(imageViewSetMutex);
415 		imageViewSet.insert(imageView);
416 	}
417 }
418 
unregisterImageView(ImageView * imageView)419 void Device::unregisterImageView(ImageView *imageView)
420 {
421 	if(imageView != nullptr)
422 	{
423 		marl::lock lock(imageViewSetMutex);
424 		auto it = imageViewSet.find(imageView);
425 		if(it != imageViewSet.end())
426 		{
427 			imageViewSet.erase(it);
428 		}
429 	}
430 }
431 
prepareForSampling(ImageView * imageView)432 void Device::prepareForSampling(ImageView *imageView)
433 {
434 	if(imageView != nullptr)
435 	{
436 		marl::lock lock(imageViewSetMutex);
437 
438 		auto it = imageViewSet.find(imageView);
439 		if(it != imageViewSet.end())
440 		{
441 			imageView->prepareForSampling();
442 		}
443 	}
444 }
445 
contentsChanged(ImageView * imageView)446 void Device::contentsChanged(ImageView *imageView)
447 {
448 	if(imageView != nullptr)
449 	{
450 		marl::lock lock(imageViewSetMutex);
451 
452 		auto it = imageViewSet.find(imageView);
453 		if(it != imageViewSet.end())
454 		{
455 			imageView->contentsChanged();
456 		}
457 	}
458 }
459 
460 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
emitDeviceMemoryReport(VkDeviceMemoryReportEventTypeEXT type,uint64_t memoryObjectId,VkDeviceSize size,VkObjectType objectType,uint64_t objectHandle,uint32_t heapIndex)461 void Device::emitDeviceMemoryReport(VkDeviceMemoryReportEventTypeEXT type, uint64_t memoryObjectId, VkDeviceSize size, VkObjectType objectType, uint64_t objectHandle, uint32_t heapIndex)
462 {
463 	if(deviceMemoryReportCallbacks.empty()) return;
464 
465 	const VkDeviceMemoryReportCallbackDataEXT callbackData = {
466 		VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT,  // sType
467 		nullptr,                                                   // pNext
468 		0,                                                         // flags
469 		type,                                                      // type
470 		memoryObjectId,                                            // memoryObjectId
471 		size,                                                      // size
472 		objectType,                                                // objectType
473 		objectHandle,                                              // objectHandle
474 		heapIndex,                                                 // heapIndex
475 	};
476 	for(const auto &callback : deviceMemoryReportCallbacks)
477 	{
478 		callback.first(&callbackData, callback.second);
479 	}
480 }
481 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
482 
483 }  // namespace vk
484