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"
52 #define VK_NULL_RETURN(STMT) \
57 } catch (const std::bad_alloc&) { \
58 return VK_ERROR_OUT_OF_HOST_MEMORY; \
59 } catch (VkResult res) { \
62 } while (deGetFalse())
64 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar
65 #define VK_NULL_FUNC_ENTRY(NAME, FUNC) { #NAME, (deFunctionPtr)FUNC }
67 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME) \
70 NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
73 VK_NULL_DEFINE_DEVICE_OBJ(Fence);
74 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
75 VK_NULL_DEFINE_DEVICE_OBJ(Event);
76 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
77 VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
78 VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
79 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
80 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
81 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
82 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
83 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
84 VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
85 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
86 VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
91 Instance (const VkInstanceCreateInfo* instanceInfo);
94 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
97 const tcu::StaticFunctionLibrary m_functions;
103 Device (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
106 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
109 const tcu::StaticFunctionLibrary m_functions;
115 Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
116 Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
119 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
121 // \todo [2015-12-03 pyry] Alignment requirements?
122 // \todo [2015-12-03 pyry] Empty allocations okay?
123 if (pAllocInfo->allocationSize > 0)
125 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
127 throw std::bad_alloc();
134 void freeHeap (void* ptr)
142 DeviceMemory (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
143 : m_memory(allocateHeap(pAllocInfo))
151 void* getPtr (void) const { return m_memory; }
154 void* const m_memory;
160 Buffer (VkDevice, const VkBufferCreateInfo* pCreateInfo)
161 : m_size(pCreateInfo->size)
164 VkDeviceSize getSize (void) const { return m_size; }
167 const VkDeviceSize m_size;
173 Image (VkDevice, const VkImageCreateInfo* pCreateInfo)
174 : m_imageType (pCreateInfo->imageType)
175 , m_format (pCreateInfo->format)
176 , m_extent (pCreateInfo->extent)
177 , m_samples (pCreateInfo->samples)
180 VkImageType getImageType (void) const { return m_imageType; }
181 VkFormat getFormat (void) const { return m_format; }
182 VkExtent3D getExtent (void) const { return m_extent; }
183 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
186 const VkImageType m_imageType;
187 const VkFormat m_format;
188 const VkExtent3D m_extent;
189 const VkSampleCountFlagBits m_samples;
195 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
202 DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
208 DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
210 , m_flags (pCreateInfo->flags)
212 ~DescriptorPool (void)
217 VkDescriptorSet allocate (VkDescriptorSetLayout setLayout);
218 void free (VkDescriptorSet set);
223 const VkDevice m_device;
224 const VkDescriptorPoolCreateFlags m_flags;
226 vector<DescriptorSet*> m_managedSets;
229 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
231 DescriptorSet* const impl = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
235 m_managedSets.push_back(impl);
243 return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
246 void DescriptorPool::free (VkDescriptorSet set)
248 DescriptorSet* const impl = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
250 DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
254 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
256 if (m_managedSets[ndx] == impl)
258 std::swap(m_managedSets[ndx], m_managedSets.back());
259 m_managedSets.pop_back();
264 DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
267 void DescriptorPool::reset (void)
269 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
270 delete m_managedSets[ndx];
271 m_managedSets.clear();
277 PFN_vkVoidFunction getInstanceProcAddr (VkInstance instance, const char* pName)
279 return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
282 PFN_vkVoidFunction getDeviceProcAddr (VkDevice device, const char* pName)
284 return reinterpret_cast<Device*>(device)->getProcAddr(pName);
287 VkResult createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks*, VkPipeline* pPipelines)
289 for (deUint32 ndx = 0; ndx < count; ndx++)
290 pPipelines[ndx] = VkPipeline((deUint64)(deUintptr)new Pipeline(device, pCreateInfos+ndx));
294 VkResult createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks*, VkPipeline* pPipelines)
296 for (deUint32 ndx = 0; ndx < count; ndx++)
297 pPipelines[ndx] = VkPipeline((deUint64)(deUintptr)new Pipeline(device, pCreateInfos+ndx));
301 VkResult enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
303 if (pDevices && *pPhysicalDeviceCount >= 1u)
304 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
306 *pPhysicalDeviceCount = 1;
311 void getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
313 deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
315 props->apiVersion = VK_API_VERSION;
316 props->driverVersion = 1u;
317 props->deviceType = VK_PHYSICAL_DEVICE_TYPE_OTHER;
319 deMemcpy(props->deviceName, "null", 5);
321 // \todo [2015-09-25 pyry] Fill in reasonable limits
322 props->limits.maxTexelBufferElements = 8096;
325 void getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
327 if (props && *count >= 1u)
329 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
331 props->queueCount = 1u;
332 props->queueFlags = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
333 props->timestampValidBits = 64;
339 void getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
341 deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
343 props->memoryTypeCount = 1u;
344 props->memoryTypes[0].heapIndex = 0u;
345 props->memoryTypes[0].propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
347 props->memoryHeapCount = 1u;
348 props->memoryHeaps[0].size = 1ull << 31;
349 props->memoryHeaps[0].flags = 0u;
352 void getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
354 const VkFormatFeatureFlags allFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
355 | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
356 | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
357 | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
358 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
359 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
360 | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
361 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
362 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
363 | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
364 | VK_FORMAT_FEATURE_BLIT_SRC_BIT
365 | VK_FORMAT_FEATURE_BLIT_DST_BIT;
367 pFormatProperties->linearTilingFeatures = allFeatures;
368 pFormatProperties->optimalTilingFeatures = allFeatures;
369 pFormatProperties->bufferFeatures = allFeatures;
372 void getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
374 const Buffer* buffer = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
376 requirements->memoryTypeBits = 1u;
377 requirements->size = buffer->getSize();
378 requirements->alignment = (VkDeviceSize)1u;
381 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
383 return (VkDeviceSize)getPixelSize(mapVkFormat(format))
384 * (VkDeviceSize)extent.width
385 * (VkDeviceSize)extent.height
386 * (VkDeviceSize)extent.depth
387 * (VkDeviceSize)samples;
390 void getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
392 const Image* image = reinterpret_cast<const Image*>(imageHandle.getInternal());
394 requirements->memoryTypeBits = 1u;
395 requirements->alignment = 4u;
396 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
399 VkResult mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
401 const DeviceMemory* memory = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
406 *ppData = (deUint8*)memory->getPtr() + offset;
411 VkResult allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
413 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
415 for (deUint32 ndx = 0; ndx < pAllocateInfo->setLayoutCount; ++ndx)
419 pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
421 catch (const std::bad_alloc&)
423 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
424 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
426 return VK_ERROR_OUT_OF_HOST_MEMORY;
430 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
431 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
440 void freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
442 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
444 for (deUint32 ndx = 0; ndx < count; ++ndx)
445 poolImpl->free(pDescriptorSets[ndx]);
448 VkResult resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
450 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
457 VkResult allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
459 if (pAllocateInfo && pCommandBuffers)
461 for (deUint32 ndx = 0; ndx < pAllocateInfo->bufferCount; ++ndx)
463 pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
470 void freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
473 DE_UNREF(commandPool);
475 for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
476 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
479 #include "vkNullDriverImpl.inl"
483 Instance::Instance (const VkInstanceCreateInfo*)
484 : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
488 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
489 : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
493 class NullDriverLibrary : public Library
496 NullDriverLibrary (void)
497 : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
498 , m_driver (m_library)
501 const PlatformInterface& getPlatformInterface (void) const { return m_driver; }
504 const tcu::StaticFunctionLibrary m_library;
505 const PlatformDriver m_driver;
510 Library* createNullDriver (void)
512 return new NullDriverLibrary();