• 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 
find(uint32_t id)108 const SamplerState *Device::SamplerIndexer::find(uint32_t id)
109 {
110 	marl::lock lock(mutex);
111 
112 	auto it = std::find_if(std::begin(map), std::end(map),
113 	                       [&id](auto &&p) { return p.second.id == id; });
114 
115 	return (it != std::end(map)) ? &(it->first) : nullptr;
116 }
117 
Device(const VkDeviceCreateInfo * pCreateInfo,void * mem,PhysicalDevice * physicalDevice,const VkPhysicalDeviceFeatures * enabledFeatures,const std::shared_ptr<marl::Scheduler> & scheduler)118 Device::Device(const VkDeviceCreateInfo *pCreateInfo, void *mem, PhysicalDevice *physicalDevice, const VkPhysicalDeviceFeatures *enabledFeatures, const std::shared_ptr<marl::Scheduler> &scheduler)
119     : physicalDevice(physicalDevice)
120     , queues(reinterpret_cast<Queue *>(mem))
121     , enabledExtensionCount(pCreateInfo->enabledExtensionCount)
122     , enabledFeatures(enabledFeatures ? *enabledFeatures : VkPhysicalDeviceFeatures{})  // "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."
123     , scheduler(scheduler)
124 {
125 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
126 	{
127 		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
128 		queueCount += queueCreateInfo.queueCount;
129 	}
130 
131 	uint32_t queueID = 0;
132 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
133 	{
134 		const VkDeviceQueueCreateInfo &queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
135 
136 		for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
137 		{
138 			new(&queues[queueID]) Queue(this, scheduler.get());
139 		}
140 	}
141 
142 	extensions = reinterpret_cast<ExtensionName *>(static_cast<uint8_t *>(mem) + (sizeof(Queue) * queueCount));
143 	for(uint32_t i = 0; i < enabledExtensionCount; i++)
144 	{
145 		strncpy(extensions[i], pCreateInfo->ppEnabledExtensionNames[i], VK_MAX_EXTENSION_NAME_SIZE);
146 	}
147 
148 	if(pCreateInfo->enabledLayerCount)
149 	{
150 		// "The ppEnabledLayerNames and enabledLayerCount members of VkDeviceCreateInfo are deprecated and their values must be ignored by implementations."
151 		UNSUPPORTED("enabledLayerCount");
152 	}
153 
154 	// FIXME (b/119409619): use an allocator here so we can control all memory allocations
155 	blitter.reset(new sw::Blitter());
156 	samplingRoutineCache.reset(new SamplingRoutineCache());
157 	samplerIndexer.reset(new SamplerIndexer());
158 
159 #ifdef ENABLE_VK_DEBUGGER
160 	static auto port = getenv("VK_DEBUGGER_PORT");
161 	if(port)
162 	{
163 		// Construct the debugger context and server - this may block for a
164 		// debugger connection, allowing breakpoints to be set before they're
165 		// executed.
166 		debugger.context = vk::dbg::Context::create();
167 		debugger.server = vk::dbg::Server::create(debugger.context, atoi(port));
168 	}
169 #endif  // ENABLE_VK_DEBUGGER
170 
171 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
172 	const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
173 	while(extensionCreateInfo)
174 	{
175 		if(extensionCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT)
176 		{
177 			auto deviceMemoryReportCreateInfo = reinterpret_cast<const VkDeviceDeviceMemoryReportCreateInfoEXT *>(pCreateInfo->pNext);
178 			if(deviceMemoryReportCreateInfo->pfnUserCallback != nullptr)
179 			{
180 				deviceMemoryReportCallbacks.emplace_back(deviceMemoryReportCreateInfo->pfnUserCallback, deviceMemoryReportCreateInfo->pUserData);
181 			}
182 		}
183 		extensionCreateInfo = extensionCreateInfo->pNext;
184 	}
185 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
186 }
187 
destroy(const VkAllocationCallbacks * pAllocator)188 void Device::destroy(const VkAllocationCallbacks *pAllocator)
189 {
190 	for(uint32_t i = 0; i < queueCount; i++)
191 	{
192 		queues[i].~Queue();
193 	}
194 
195 	vk::freeHostMemory(queues, pAllocator);
196 }
197 
ComputeRequiredAllocationSize(const VkDeviceCreateInfo * pCreateInfo)198 size_t Device::ComputeRequiredAllocationSize(const VkDeviceCreateInfo *pCreateInfo)
199 {
200 	uint32_t queueCount = 0;
201 	for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
202 	{
203 		queueCount += pCreateInfo->pQueueCreateInfos[i].queueCount;
204 	}
205 
206 	return (sizeof(Queue) * queueCount) + (pCreateInfo->enabledExtensionCount * sizeof(ExtensionName));
207 }
208 
hasExtension(const char * extensionName) const209 bool Device::hasExtension(const char *extensionName) const
210 {
211 	for(uint32_t i = 0; i < enabledExtensionCount; i++)
212 	{
213 		if(strncmp(extensions[i], extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0)
214 		{
215 			return true;
216 		}
217 	}
218 	return false;
219 }
220 
getQueue(uint32_t queueFamilyIndex,uint32_t queueIndex) const221 VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
222 {
223 	ASSERT(queueFamilyIndex == 0);
224 
225 	return queues[queueIndex];
226 }
227 
waitForFences(uint32_t fenceCount,const VkFence * pFences,VkBool32 waitAll,uint64_t timeout)228 VkResult Device::waitForFences(uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout)
229 {
230 	bool infiniteTimeout = false;
231 	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);
232 
233 	if(waitAll != VK_FALSE)  // All fences must be signaled
234 	{
235 		for(uint32_t i = 0; i < fenceCount; i++)
236 		{
237 			if(timeout == 0)
238 			{
239 				if(Cast(pFences[i])->getStatus() != VK_SUCCESS)  // At least one fence is not signaled
240 				{
241 					return VK_TIMEOUT;
242 				}
243 			}
244 			else if(infiniteTimeout)
245 			{
246 				if(Cast(pFences[i])->wait() != VK_SUCCESS)  // At least one fence is not signaled
247 				{
248 					return VK_TIMEOUT;
249 				}
250 			}
251 			else
252 			{
253 				if(Cast(pFences[i])->wait(end_ns) != VK_SUCCESS)  // At least one fence is not signaled
254 				{
255 					return VK_TIMEOUT;
256 				}
257 			}
258 		}
259 
260 		return VK_SUCCESS;
261 	}
262 	else  // At least one fence must be signaled
263 	{
264 		marl::containers::vector<marl::Event, 8> events;
265 		for(uint32_t i = 0; i < fenceCount; i++)
266 		{
267 			events.push_back(Cast(pFences[i])->getCountedEvent()->event());
268 		}
269 
270 		auto any = marl::Event::any(events.begin(), events.end());
271 
272 		if(timeout == 0)
273 		{
274 			return any.isSignalled() ? VK_SUCCESS : VK_TIMEOUT;
275 		}
276 		else if(infiniteTimeout)
277 		{
278 			any.wait();
279 			return VK_SUCCESS;
280 		}
281 		else
282 		{
283 			return any.wait_until(end_ns) ? VK_SUCCESS : VK_TIMEOUT;
284 		}
285 	}
286 }
287 
waitForSemaphores(const VkSemaphoreWaitInfo * pWaitInfo,uint64_t timeout)288 VkResult Device::waitForSemaphores(const VkSemaphoreWaitInfo *pWaitInfo, uint64_t timeout)
289 {
290 	bool infiniteTimeout = false;
291 	const time_point end_ns = getEndTimePoint(timeout, infiniteTimeout);
292 
293 	if(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT)
294 	{
295 		TimelineSemaphore any = TimelineSemaphore();
296 
297 		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
298 		{
299 			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
300 			uint64_t waitValue = pWaitInfo->pValues[i];
301 
302 			if(semaphore->getCounterValue() == waitValue)
303 			{
304 				return VK_SUCCESS;
305 			}
306 
307 			semaphore->addDependent(any, waitValue);
308 		}
309 
310 		if(infiniteTimeout)
311 		{
312 			any.wait(1ull);
313 			return VK_SUCCESS;
314 		}
315 		else
316 		{
317 			if(any.wait(1, end_ns) == VK_SUCCESS)
318 			{
319 				return VK_SUCCESS;
320 			}
321 		}
322 
323 		return VK_TIMEOUT;
324 	}
325 	else
326 	{
327 		ASSERT(pWaitInfo->flags == 0);
328 		for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; i++)
329 		{
330 			TimelineSemaphore *semaphore = DynamicCast<TimelineSemaphore>(pWaitInfo->pSemaphores[i]);
331 			uint64_t value = pWaitInfo->pValues[i];
332 			if(infiniteTimeout)
333 			{
334 				semaphore->wait(value);
335 			}
336 			else if(semaphore->wait(pWaitInfo->pValues[i], end_ns) != VK_SUCCESS)
337 			{
338 				return VK_TIMEOUT;
339 			}
340 		}
341 		return VK_SUCCESS;
342 	}
343 }
344 
waitIdle()345 VkResult Device::waitIdle()
346 {
347 	for(uint32_t i = 0; i < queueCount; i++)
348 	{
349 		queues[i].waitIdle();
350 	}
351 
352 	return VK_SUCCESS;
353 }
354 
getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo * pCreateInfo,VkDescriptorSetLayoutSupport * pSupport) const355 void Device::getDescriptorSetLayoutSupport(const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
356                                            VkDescriptorSetLayoutSupport *pSupport) const
357 {
358 	// From Vulkan Spec 13.2.1 Descriptor Set Layout, in description of vkGetDescriptorSetLayoutSupport:
359 	// "This command does not consider other limits such as maxPerStageDescriptor*, and so a descriptor
360 	// set layout that is supported according to this command must still satisfy the pipeline layout limits
361 	// such as maxPerStageDescriptor* in order to be used in a pipeline layout."
362 
363 	// We have no "strange" limitations to enforce beyond the device limits, so we can safely always claim support.
364 	pSupport->supported = VK_TRUE;
365 }
366 
updateDescriptorSets(uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)367 void Device::updateDescriptorSets(uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites,
368                                   uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies)
369 {
370 	for(uint32_t i = 0; i < descriptorWriteCount; i++)
371 	{
372 		DescriptorSetLayout::WriteDescriptorSet(this, pDescriptorWrites[i]);
373 	}
374 
375 	for(uint32_t i = 0; i < descriptorCopyCount; i++)
376 	{
377 		DescriptorSetLayout::CopyDescriptorSet(pDescriptorCopies[i]);
378 	}
379 }
380 
getRequirements(VkMemoryDedicatedRequirements * requirements) const381 void Device::getRequirements(VkMemoryDedicatedRequirements *requirements) const
382 {
383 	requirements->prefersDedicatedAllocation = VK_FALSE;
384 	requirements->requiresDedicatedAllocation = VK_FALSE;
385 }
386 
getSamplingRoutineCache() const387 Device::SamplingRoutineCache *Device::getSamplingRoutineCache() const
388 {
389 	return samplingRoutineCache.get();
390 }
391 
updateSamplingRoutineSnapshotCache()392 void Device::updateSamplingRoutineSnapshotCache()
393 {
394 	samplingRoutineCache->updateSnapshot();
395 }
396 
indexSampler(const SamplerState & samplerState)397 uint32_t Device::indexSampler(const SamplerState &samplerState)
398 {
399 	return samplerIndexer->index(samplerState);
400 }
401 
removeSampler(const SamplerState & samplerState)402 void Device::removeSampler(const SamplerState &samplerState)
403 {
404 	samplerIndexer->remove(samplerState);
405 }
406 
findSampler(uint32_t samplerId) const407 const SamplerState *Device::findSampler(uint32_t samplerId) const
408 {
409 	return samplerIndexer->find(samplerId);
410 }
411 
setDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT * pNameInfo)412 VkResult Device::setDebugUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
413 {
414 	// Optionally maps user-friendly name to an object
415 	return VK_SUCCESS;
416 }
417 
setDebugUtilsObjectTag(const VkDebugUtilsObjectTagInfoEXT * pTagInfo)418 VkResult Device::setDebugUtilsObjectTag(const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
419 {
420 	// Optionally attach arbitrary data to an object
421 	return VK_SUCCESS;
422 }
423 
registerImageView(ImageView * imageView)424 void Device::registerImageView(ImageView *imageView)
425 {
426 	if(imageView != nullptr)
427 	{
428 		marl::lock lock(imageViewSetMutex);
429 		imageViewSet.insert(imageView);
430 	}
431 }
432 
unregisterImageView(ImageView * imageView)433 void Device::unregisterImageView(ImageView *imageView)
434 {
435 	if(imageView != nullptr)
436 	{
437 		marl::lock lock(imageViewSetMutex);
438 		auto it = imageViewSet.find(imageView);
439 		if(it != imageViewSet.end())
440 		{
441 			imageViewSet.erase(it);
442 		}
443 	}
444 }
445 
prepareForSampling(ImageView * imageView)446 void Device::prepareForSampling(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->prepareForSampling();
456 		}
457 	}
458 }
459 
contentsChanged(ImageView * imageView,Image::ContentsChangedContext context)460 void Device::contentsChanged(ImageView *imageView, Image::ContentsChangedContext context)
461 {
462 	if(imageView != nullptr)
463 	{
464 		marl::lock lock(imageViewSetMutex);
465 
466 		auto it = imageViewSet.find(imageView);
467 		if(it != imageViewSet.end())
468 		{
469 			imageView->contentsChanged(context);
470 		}
471 	}
472 }
473 
setPrivateData(VkObjectType objectType,uint64_t objectHandle,const PrivateData * privateDataSlot,uint64_t data)474 VkResult Device::setPrivateData(VkObjectType objectType, uint64_t objectHandle, const PrivateData *privateDataSlot, uint64_t data)
475 {
476 	marl::lock lock(privateDataMutex);
477 
478 	auto &privateDataSlotMap = privateData[privateDataSlot];
479 	const PrivateDataObject privateDataObject = { objectType, objectHandle };
480 	privateDataSlotMap[privateDataObject] = data;
481 	return VK_SUCCESS;
482 }
483 
getPrivateData(VkObjectType objectType,uint64_t objectHandle,const PrivateData * privateDataSlot,uint64_t * data)484 void Device::getPrivateData(VkObjectType objectType, uint64_t objectHandle, const PrivateData *privateDataSlot, uint64_t *data)
485 {
486 	marl::lock lock(privateDataMutex);
487 
488 	*data = 0;
489 	auto it = privateData.find(privateDataSlot);
490 	if(it != privateData.end())
491 	{
492 		auto &privateDataSlotMap = it->second;
493 		const PrivateDataObject privateDataObject = { objectType, objectHandle };
494 		auto it2 = privateDataSlotMap.find(privateDataObject);
495 		if(it2 != privateDataSlotMap.end())
496 		{
497 			*data = it2->second;
498 		}
499 	}
500 }
501 
removePrivateDataSlot(const PrivateData * privateDataSlot)502 void Device::removePrivateDataSlot(const PrivateData *privateDataSlot)
503 {
504 	marl::lock lock(privateDataMutex);
505 
506 	privateData.erase(privateDataSlot);
507 }
508 
509 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
emitDeviceMemoryReport(VkDeviceMemoryReportEventTypeEXT type,uint64_t memoryObjectId,VkDeviceSize size,VkObjectType objectType,uint64_t objectHandle,uint32_t heapIndex)510 void Device::emitDeviceMemoryReport(VkDeviceMemoryReportEventTypeEXT type, uint64_t memoryObjectId, VkDeviceSize size, VkObjectType objectType, uint64_t objectHandle, uint32_t heapIndex)
511 {
512 	if(deviceMemoryReportCallbacks.empty()) return;
513 
514 	const VkDeviceMemoryReportCallbackDataEXT callbackData = {
515 		VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT,  // sType
516 		nullptr,                                                   // pNext
517 		0,                                                         // flags
518 		type,                                                      // type
519 		memoryObjectId,                                            // memoryObjectId
520 		size,                                                      // size
521 		objectType,                                                // objectType
522 		objectHandle,                                              // objectHandle
523 		heapIndex,                                                 // heapIndex
524 	};
525 	for(const auto &callback : deviceMemoryReportCallbacks)
526 	{
527 		callback.first(&callbackData, callback.second);
528 	}
529 }
530 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
531 
532 }  // namespace vk
533