1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Null (dummy) Vulkan implementation.
33 *//*--------------------------------------------------------------------*/
35 #include "vkNullDriver.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkImageUtil.hpp"
38 #include "tcuFunctionLibrary.hpp"
55 void* allocateSystemMem (const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope scope)
57 void* ptr = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(T), sizeof(void*), scope);
59 throw std::bad_alloc();
63 void freeSystemMem (const VkAllocationCallbacks* pAllocator, void* mem)
65 pAllocator->pfnFree(pAllocator->pUserData, mem);
68 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
69 Handle allocateHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
71 Object* obj = DE_NULL;
75 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
78 obj = new (mem) Object(parent, pCreateInfo);
79 DE_ASSERT(obj == mem);
83 pAllocator->pfnFree(pAllocator->pUserData, mem);
88 obj = new Object(parent, pCreateInfo);
90 return reinterpret_cast<Handle>(obj);
93 template<typename Object, typename Handle, typename CreateInfo>
94 Handle allocateHandle (const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
96 Object* obj = DE_NULL;
100 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
103 obj = new (mem) Object(pCreateInfo);
104 DE_ASSERT(obj == mem);
108 pAllocator->pfnFree(pAllocator->pUserData, mem);
113 obj = new Object(pCreateInfo);
115 return reinterpret_cast<Handle>(obj);
118 template<typename Object, typename Handle>
119 void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
121 Object* obj = reinterpret_cast<Object*>(handle);
126 freeSystemMem(pAllocator, reinterpret_cast<void*>(obj));
132 template<typename Object, typename Handle, typename CreateInfo>
133 Handle allocateNonDispHandle (VkDevice device, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
135 Object* const obj = allocateHandle<Object, Object*>(device, pCreateInfo, pAllocator);
136 return Handle((deUint64)(deUintptr)obj);
139 template<typename Object, typename Handle>
140 void freeNonDispHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
142 freeHandle<Object>(reinterpret_cast<Object*>((deUintptr)handle.getInternal()), pAllocator);
145 // Object definitions
147 #define VK_NULL_RETURN(STMT) \
152 } catch (const std::bad_alloc&) { \
153 return VK_ERROR_OUT_OF_HOST_MEMORY; \
154 } catch (VkResult res) { \
157 } while (deGetFalse())
159 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar
160 #define VK_NULL_FUNC_ENTRY(NAME, FUNC) { #NAME, (deFunctionPtr)FUNC }
162 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME) \
165 NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
168 VK_NULL_DEFINE_DEVICE_OBJ(Fence);
169 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
170 VK_NULL_DEFINE_DEVICE_OBJ(Event);
171 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
172 VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
173 VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
174 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
175 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
176 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
177 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
178 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
179 VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
180 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
181 VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
186 Instance (const VkInstanceCreateInfo* instanceInfo);
189 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
192 const tcu::StaticFunctionLibrary m_functions;
198 Device (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
201 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
204 const tcu::StaticFunctionLibrary m_functions;
210 Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
211 Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
214 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
216 // \todo [2015-12-03 pyry] Alignment requirements?
217 // \todo [2015-12-03 pyry] Empty allocations okay?
218 if (pAllocInfo->allocationSize > 0)
220 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
222 throw std::bad_alloc();
229 void freeHeap (void* ptr)
237 DeviceMemory (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
238 : m_memory(allocateHeap(pAllocInfo))
246 void* getPtr (void) const { return m_memory; }
249 void* const m_memory;
255 Buffer (VkDevice, const VkBufferCreateInfo* pCreateInfo)
256 : m_size(pCreateInfo->size)
259 VkDeviceSize getSize (void) const { return m_size; }
262 const VkDeviceSize m_size;
268 Image (VkDevice, const VkImageCreateInfo* pCreateInfo)
269 : m_imageType (pCreateInfo->imageType)
270 , m_format (pCreateInfo->format)
271 , m_extent (pCreateInfo->extent)
272 , m_samples (pCreateInfo->samples)
275 VkImageType getImageType (void) const { return m_imageType; }
276 VkFormat getFormat (void) const { return m_format; }
277 VkExtent3D getExtent (void) const { return m_extent; }
278 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
281 const VkImageType m_imageType;
282 const VkFormat m_format;
283 const VkExtent3D m_extent;
284 const VkSampleCountFlagBits m_samples;
290 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
297 DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
303 DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
305 , m_flags (pCreateInfo->flags)
307 ~DescriptorPool (void)
312 VkDescriptorSet allocate (VkDescriptorSetLayout setLayout);
313 void free (VkDescriptorSet set);
318 const VkDevice m_device;
319 const VkDescriptorPoolCreateFlags m_flags;
321 vector<DescriptorSet*> m_managedSets;
324 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
326 DescriptorSet* const impl = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
330 m_managedSets.push_back(impl);
338 return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
341 void DescriptorPool::free (VkDescriptorSet set)
343 DescriptorSet* const impl = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
345 DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
349 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
351 if (m_managedSets[ndx] == impl)
353 std::swap(m_managedSets[ndx], m_managedSets.back());
354 m_managedSets.pop_back();
359 DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
362 void DescriptorPool::reset (void)
364 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
365 delete m_managedSets[ndx];
366 m_managedSets.clear();
369 // API implementation
374 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
376 return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
379 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
381 return reinterpret_cast<Device*>(device)->getProcAddr(pName);
384 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
389 for (allocNdx = 0; allocNdx < count; allocNdx++)
390 pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
394 catch (const std::bad_alloc&)
396 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
397 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
399 return VK_ERROR_OUT_OF_HOST_MEMORY;
403 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
404 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
410 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
415 for (allocNdx = 0; allocNdx < count; allocNdx++)
416 pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
420 catch (const std::bad_alloc&)
422 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
423 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
425 return VK_ERROR_OUT_OF_HOST_MEMORY;
429 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
430 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
436 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
438 if (pDevices && *pPhysicalDeviceCount >= 1u)
439 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
441 *pPhysicalDeviceCount = 1;
446 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
448 deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
450 props->apiVersion = VK_API_VERSION;
451 props->driverVersion = 1u;
452 props->deviceType = VK_PHYSICAL_DEVICE_TYPE_OTHER;
454 deMemcpy(props->deviceName, "null", 5);
456 // \todo [2015-09-25 pyry] Fill in reasonable limits
457 props->limits.maxTexelBufferElements = 8096;
460 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
462 if (props && *count >= 1u)
464 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
466 props->queueCount = 1u;
467 props->queueFlags = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
468 props->timestampValidBits = 64;
474 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
476 deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
478 props->memoryTypeCount = 1u;
479 props->memoryTypes[0].heapIndex = 0u;
480 props->memoryTypes[0].propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
482 props->memoryHeapCount = 1u;
483 props->memoryHeaps[0].size = 1ull << 31;
484 props->memoryHeaps[0].flags = 0u;
487 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
489 const VkFormatFeatureFlags allFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
490 | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
491 | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
492 | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
493 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
494 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
495 | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
496 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
497 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
498 | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
499 | VK_FORMAT_FEATURE_BLIT_SRC_BIT
500 | VK_FORMAT_FEATURE_BLIT_DST_BIT;
502 pFormatProperties->linearTilingFeatures = allFeatures;
503 pFormatProperties->optimalTilingFeatures = allFeatures;
504 pFormatProperties->bufferFeatures = allFeatures;
507 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
509 const Buffer* buffer = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
511 requirements->memoryTypeBits = 1u;
512 requirements->size = buffer->getSize();
513 requirements->alignment = (VkDeviceSize)1u;
516 VKAPI_ATTR VkDeviceSize VKAPI_CALL getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
518 return (VkDeviceSize)getPixelSize(mapVkFormat(format))
519 * (VkDeviceSize)extent.width
520 * (VkDeviceSize)extent.height
521 * (VkDeviceSize)extent.depth
522 * (VkDeviceSize)samples;
525 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
527 const Image* image = reinterpret_cast<const Image*>(imageHandle.getInternal());
529 requirements->memoryTypeBits = 1u;
530 requirements->alignment = 4u;
531 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
534 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
536 const DeviceMemory* memory = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
541 *ppData = (deUint8*)memory->getPtr() + offset;
546 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
548 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
550 for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
554 pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
556 catch (const std::bad_alloc&)
558 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
559 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
561 return VK_ERROR_OUT_OF_HOST_MEMORY;
565 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
566 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
575 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
577 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
579 for (deUint32 ndx = 0; ndx < count; ++ndx)
580 poolImpl->free(pDescriptorSets[ndx]);
583 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
585 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
592 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
594 if (pAllocateInfo && pCommandBuffers)
596 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
598 pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
605 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
608 DE_UNREF(commandPool);
610 for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
611 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
614 #include "vkNullDriverImpl.inl"
618 Instance::Instance (const VkInstanceCreateInfo*)
619 : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
623 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
624 : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
628 class NullDriverLibrary : public Library
631 NullDriverLibrary (void)
632 : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
633 , m_driver (m_library)
636 const PlatformInterface& getPlatformInterface (void) const { return m_driver; }
639 const tcu::StaticFunctionLibrary m_library;
640 const PlatformDriver m_driver;
645 Library* createNullDriver (void)
647 return new NullDriverLibrary();