Improve Vulkan null driver
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkNullDriver.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
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:
14  *
15  * The above copyright notice(s) and this permission notice shall be
16  * included in all copies or substantial portions of the Materials.
17  *
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.
21  *
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.
29  *
30  *//*!
31  * \file
32  * \brief Null (dummy) Vulkan implementation.
33  *//*--------------------------------------------------------------------*/
34
35 #include "vkNullDriver.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkImageUtil.hpp"
38 #include "tcuFunctionLibrary.hpp"
39 #include "deMemory.h"
40
41 #include <stdexcept>
42 #include <algorithm>
43
44 namespace vk
45 {
46
47 namespace
48 {
49
50 using std::vector;
51
52 #define VK_NULL_RETURN(STMT)                                    \
53         do {                                                                            \
54                 try {                                                                   \
55                         STMT;                                                           \
56                         return VK_SUCCESS;                                      \
57                 } catch (const std::bad_alloc&) {               \
58                         return VK_ERROR_OUT_OF_HOST_MEMORY;     \
59                 } catch (VkResult res) {                                \
60                         return res;                                                     \
61                 }                                                                               \
62         } while (deGetFalse())
63
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 }
66
67 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME)                         \
68 struct NAME                                                                                     \
69 {                                                                                                       \
70         NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
71 }
72
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);
87
88 class Instance
89 {
90 public:
91                                                                                 Instance                (const VkInstanceCreateInfo* instanceInfo);
92                                                                                 ~Instance               (void) {}
93
94         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
95
96 private:
97         const tcu::StaticFunctionLibrary        m_functions;
98 };
99
100 class Device
101 {
102 public:
103                                                                                 Device                  (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
104                                                                                 ~Device                 (void) {}
105
106         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
107
108 private:
109         const tcu::StaticFunctionLibrary        m_functions;
110 };
111
112 class Pipeline
113 {
114 public:
115         Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
116         Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
117 };
118
119 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
120 {
121         // \todo [2015-12-03 pyry] Alignment requirements?
122         // \todo [2015-12-03 pyry] Empty allocations okay?
123         if (pAllocInfo->allocationSize > 0)
124         {
125                 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
126                 if (!heapPtr)
127                         throw std::bad_alloc();
128                 return heapPtr;
129         }
130         else
131                 return DE_NULL;
132 }
133
134 void freeHeap (void* ptr)
135 {
136         deFree(ptr);
137 }
138
139 class DeviceMemory
140 {
141 public:
142                                                 DeviceMemory    (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
143                                                         : m_memory(allocateHeap(pAllocInfo))
144                                                 {
145                                                 }
146                                                 ~DeviceMemory   (void)
147                                                 {
148                                                         freeHeap(m_memory);
149                                                 }
150
151         void*                           getPtr                  (void) const { return m_memory; }
152
153 private:
154         void* const                     m_memory;
155 };
156
157 class Buffer
158 {
159 public:
160                                                 Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
161                                                         : m_size(pCreateInfo->size)
162                                                 {}
163
164         VkDeviceSize            getSize         (void) const { return m_size;   }
165
166 private:
167         const VkDeviceSize      m_size;
168 };
169
170 class Image
171 {
172 public:
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)
178                                                                 {}
179
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;        }
184
185 private:
186         const VkImageType                       m_imageType;
187         const VkFormat                          m_format;
188         const VkExtent3D                        m_extent;
189         const VkSampleCountFlagBits     m_samples;
190 };
191
192 class CommandBuffer
193 {
194 public:
195                                                 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
196                                                 {}
197 };
198
199 class DescriptorSet
200 {
201 public:
202         DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
203 };
204
205 class DescriptorPool
206 {
207 public:
208                                                                                 DescriptorPool  (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
209                                                                                         : m_device      (device)
210                                                                                         , m_flags       (pCreateInfo->flags)
211                                                                                 {}
212                                                                                 ~DescriptorPool (void)
213                                                                                 {
214                                                                                         reset();
215                                                                                 }
216
217         VkDescriptorSet                                         allocate                (VkDescriptorSetLayout setLayout);
218         void                                                            free                    (VkDescriptorSet set);
219
220         void                                                            reset                   (void);
221
222 private:
223         const VkDevice                                          m_device;
224         const VkDescriptorPoolCreateFlags       m_flags;
225
226         vector<DescriptorSet*>                          m_managedSets;
227 };
228
229 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
230 {
231         DescriptorSet* const    impl    = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
232
233         try
234         {
235                 m_managedSets.push_back(impl);
236         }
237         catch (...)
238         {
239                 delete impl;
240                 throw;
241         }
242
243         return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
244 }
245
246 void DescriptorPool::free (VkDescriptorSet set)
247 {
248         DescriptorSet* const    impl    = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
249
250         DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
251
252         delete impl;
253
254         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
255         {
256                 if (m_managedSets[ndx] == impl)
257                 {
258                         std::swap(m_managedSets[ndx], m_managedSets.back());
259                         m_managedSets.pop_back();
260                         return;
261                 }
262         }
263
264         DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
265 }
266
267 void DescriptorPool::reset (void)
268 {
269         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
270                 delete m_managedSets[ndx];
271         m_managedSets.clear();
272 }
273
274 extern "C"
275 {
276
277 PFN_vkVoidFunction getInstanceProcAddr (VkInstance instance, const char* pName)
278 {
279         return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
280 }
281
282 PFN_vkVoidFunction getDeviceProcAddr (VkDevice device, const char* pName)
283 {
284         return reinterpret_cast<Device*>(device)->getProcAddr(pName);
285 }
286
287 VkResult createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks*, VkPipeline* pPipelines)
288 {
289         for (deUint32 ndx = 0; ndx < count; ndx++)
290                 pPipelines[ndx] = VkPipeline((deUint64)(deUintptr)new Pipeline(device, pCreateInfos+ndx));
291         return VK_SUCCESS;
292 }
293
294 VkResult createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks*, VkPipeline* pPipelines)
295 {
296         for (deUint32 ndx = 0; ndx < count; ndx++)
297                 pPipelines[ndx] = VkPipeline((deUint64)(deUintptr)new Pipeline(device, pCreateInfos+ndx));
298         return VK_SUCCESS;
299 }
300
301 VkResult enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
302 {
303         if (pDevices && *pPhysicalDeviceCount >= 1u)
304                 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
305
306         *pPhysicalDeviceCount = 1;
307
308         return VK_SUCCESS;
309 }
310
311 void getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
312 {
313         deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
314
315         props->apiVersion               = VK_API_VERSION;
316         props->driverVersion    = 1u;
317         props->deviceType               = VK_PHYSICAL_DEVICE_TYPE_OTHER;
318
319         deMemcpy(props->deviceName, "null", 5);
320
321         // \todo [2015-09-25 pyry] Fill in reasonable limits
322         props->limits.maxTexelBufferElements    = 8096;
323 }
324
325 void getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
326 {
327         if (props && *count >= 1u)
328         {
329                 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
330
331                 props->queueCount                       = 1u;
332                 props->queueFlags                       = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
333                 props->timestampValidBits       = 64;
334         }
335
336         *count = 1u;
337 }
338
339 void getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
340 {
341         deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
342
343         props->memoryTypeCount                          = 1u;
344         props->memoryTypes[0].heapIndex         = 0u;
345         props->memoryTypes[0].propertyFlags     = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
346
347         props->memoryHeapCount                          = 1u;
348         props->memoryHeaps[0].size                      = 1ull << 31;
349         props->memoryHeaps[0].flags                     = 0u;
350 }
351
352 void getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
353 {
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;
366
367         pFormatProperties->linearTilingFeatures         = allFeatures;
368         pFormatProperties->optimalTilingFeatures        = allFeatures;
369         pFormatProperties->bufferFeatures                       = allFeatures;
370 }
371
372 void getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
373 {
374         const Buffer*   buffer  = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
375
376         requirements->memoryTypeBits    = 1u;
377         requirements->size                              = buffer->getSize();
378         requirements->alignment                 = (VkDeviceSize)1u;
379 }
380
381 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
382 {
383         return (VkDeviceSize)getPixelSize(mapVkFormat(format))
384                         * (VkDeviceSize)extent.width
385                         * (VkDeviceSize)extent.height
386                         * (VkDeviceSize)extent.depth
387                         * (VkDeviceSize)samples;
388 }
389
390 void getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
391 {
392         const Image*    image   = reinterpret_cast<const Image*>(imageHandle.getInternal());
393
394         requirements->memoryTypeBits    = 1u;
395         requirements->alignment                 = 4u;
396         requirements->size                              = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
397 }
398
399 VkResult mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
400 {
401         const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
402
403         DE_UNREF(size);
404         DE_UNREF(flags);
405
406         *ppData = (deUint8*)memory->getPtr() + offset;
407
408         return VK_SUCCESS;
409 }
410
411 VkResult allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
412 {
413         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
414
415         for (deUint32 ndx = 0; ndx < pAllocateInfo->setLayoutCount; ++ndx)
416         {
417                 try
418                 {
419                         pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
420                 }
421                 catch (const std::bad_alloc&)
422                 {
423                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
424                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
425
426                         return VK_ERROR_OUT_OF_HOST_MEMORY;
427                 }
428                 catch (VkResult res)
429                 {
430                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
431                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
432
433                         return res;
434                 }
435         }
436
437         return VK_SUCCESS;
438 }
439
440 void freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
441 {
442         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
443
444         for (deUint32 ndx = 0; ndx < count; ++ndx)
445                 poolImpl->free(pDescriptorSets[ndx]);
446 }
447
448 VkResult resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
449 {
450         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
451
452         poolImpl->reset();
453
454         return VK_SUCCESS;
455 }
456
457 VkResult allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
458 {
459         if (pAllocateInfo && pCommandBuffers)
460         {
461                 for (deUint32 ndx = 0; ndx < pAllocateInfo->bufferCount; ++ndx)
462                 {
463                         pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
464                 }
465         }
466
467         return VK_SUCCESS;
468 }
469
470 void freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
471 {
472         DE_UNREF(device);
473         DE_UNREF(commandPool);
474
475         for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
476                 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
477 }
478
479 #include "vkNullDriverImpl.inl"
480
481 } // extern "C"
482
483 Instance::Instance (const VkInstanceCreateInfo*)
484         : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
485 {
486 }
487
488 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
489         : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
490 {
491 }
492
493 class NullDriverLibrary : public Library
494 {
495 public:
496                                                                                 NullDriverLibrary (void)
497                                                                                         : m_library     (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
498                                                                                         , m_driver      (m_library)
499                                                                                 {}
500
501         const PlatformInterface&                        getPlatformInterface    (void) const { return m_driver; }
502
503 private:
504         const tcu::StaticFunctionLibrary        m_library;
505         const PlatformDriver                            m_driver;
506 };
507
508 } // anonymous
509
510 Library* createNullDriver (void)
511 {
512         return new NullDriverLibrary();
513 }
514
515 } // vk