Update Vulkan framework to API 1.0.5
[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  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Null (dummy) Vulkan implementation.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vkNullDriver.hpp"
25 #include "vkPlatform.hpp"
26 #include "vkImageUtil.hpp"
27 #include "tcuFunctionLibrary.hpp"
28 #include "deMemory.h"
29
30 #include <stdexcept>
31 #include <algorithm>
32
33 namespace vk
34 {
35
36 namespace
37 {
38
39 using std::vector;
40
41 // Memory management
42
43 template<typename T>
44 void* allocateSystemMem (const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope scope)
45 {
46         void* ptr = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(T), sizeof(void*), scope);
47         if (!ptr)
48                 throw std::bad_alloc();
49         return ptr;
50 }
51
52 void freeSystemMem (const VkAllocationCallbacks* pAllocator, void* mem)
53 {
54         pAllocator->pfnFree(pAllocator->pUserData, mem);
55 }
56
57 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
58 Handle allocateHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
59 {
60         Object* obj = DE_NULL;
61
62         if (pAllocator)
63         {
64                 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
65                 try
66                 {
67                         obj = new (mem) Object(parent, pCreateInfo);
68                         DE_ASSERT(obj == mem);
69                 }
70                 catch (...)
71                 {
72                         pAllocator->pfnFree(pAllocator->pUserData, mem);
73                         throw;
74                 }
75         }
76         else
77                 obj = new Object(parent, pCreateInfo);
78
79         return reinterpret_cast<Handle>(obj);
80 }
81
82 template<typename Object, typename Handle, typename CreateInfo>
83 Handle allocateHandle (const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
84 {
85         Object* obj = DE_NULL;
86
87         if (pAllocator)
88         {
89                 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
90                 try
91                 {
92                         obj = new (mem) Object(pCreateInfo);
93                         DE_ASSERT(obj == mem);
94                 }
95                 catch (...)
96                 {
97                         pAllocator->pfnFree(pAllocator->pUserData, mem);
98                         throw;
99                 }
100         }
101         else
102                 obj = new Object(pCreateInfo);
103
104         return reinterpret_cast<Handle>(obj);
105 }
106
107 template<typename Object, typename Handle>
108 void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
109 {
110         Object* obj = reinterpret_cast<Object*>(handle);
111
112         if (pAllocator)
113         {
114                 obj->~Object();
115                 freeSystemMem(pAllocator, reinterpret_cast<void*>(obj));
116         }
117         else
118                 delete obj;
119 }
120
121 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
122 Handle allocateNonDispHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
123 {
124         Object* const   obj             = allocateHandle<Object, Object*>(parent, pCreateInfo, pAllocator);
125         return Handle((deUint64)(deUintptr)obj);
126 }
127
128 template<typename Object, typename Handle>
129 void freeNonDispHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
130 {
131         freeHandle<Object>(reinterpret_cast<Object*>((deUintptr)handle.getInternal()), pAllocator);
132 }
133
134 // Object definitions
135
136 #define VK_NULL_RETURN(STMT)                                    \
137         do {                                                                            \
138                 try {                                                                   \
139                         STMT;                                                           \
140                         return VK_SUCCESS;                                      \
141                 } catch (const std::bad_alloc&) {               \
142                         return VK_ERROR_OUT_OF_HOST_MEMORY;     \
143                 } catch (VkResult res) {                                \
144                         return res;                                                     \
145                 }                                                                               \
146         } while (deGetFalse())
147
148 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar
149 #define VK_NULL_FUNC_ENTRY(NAME, FUNC)  { #NAME, (deFunctionPtr)FUNC }
150
151 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME)                         \
152 struct NAME                                                                                     \
153 {                                                                                                       \
154         NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
155 }
156
157 VK_NULL_DEFINE_DEVICE_OBJ(Fence);
158 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
159 VK_NULL_DEFINE_DEVICE_OBJ(Event);
160 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
161 VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
162 VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
163 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
164 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
165 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
166 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
167 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
168 VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
169 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
170 VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
171
172 class Instance
173 {
174 public:
175                                                                                 Instance                (const VkInstanceCreateInfo* instanceInfo);
176                                                                                 ~Instance               (void) {}
177
178         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
179
180 private:
181         const tcu::StaticFunctionLibrary        m_functions;
182 };
183
184 class DebugReportCallbackEXT
185 {
186 public:
187                                                                                 DebugReportCallbackEXT  (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {}
188                                                                                 ~DebugReportCallbackEXT (void) {}
189 };
190
191 class Device
192 {
193 public:
194                                                                                 Device                  (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
195                                                                                 ~Device                 (void) {}
196
197         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
198
199 private:
200         const tcu::StaticFunctionLibrary        m_functions;
201 };
202
203 class Pipeline
204 {
205 public:
206         Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
207         Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
208 };
209
210 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
211 {
212         // \todo [2015-12-03 pyry] Alignment requirements?
213         // \todo [2015-12-03 pyry] Empty allocations okay?
214         if (pAllocInfo->allocationSize > 0)
215         {
216                 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
217                 if (!heapPtr)
218                         throw std::bad_alloc();
219                 return heapPtr;
220         }
221         else
222                 return DE_NULL;
223 }
224
225 void freeHeap (void* ptr)
226 {
227         deFree(ptr);
228 }
229
230 class DeviceMemory
231 {
232 public:
233                                                 DeviceMemory    (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
234                                                         : m_memory(allocateHeap(pAllocInfo))
235                                                 {
236                                                 }
237                                                 ~DeviceMemory   (void)
238                                                 {
239                                                         freeHeap(m_memory);
240                                                 }
241
242         void*                           getPtr                  (void) const { return m_memory; }
243
244 private:
245         void* const                     m_memory;
246 };
247
248 class Buffer
249 {
250 public:
251                                                 Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
252                                                         : m_size(pCreateInfo->size)
253                                                 {}
254
255         VkDeviceSize            getSize         (void) const { return m_size;   }
256
257 private:
258         const VkDeviceSize      m_size;
259 };
260
261 class Image
262 {
263 public:
264                                                                 Image                   (VkDevice, const VkImageCreateInfo* pCreateInfo)
265                                                                         : m_imageType   (pCreateInfo->imageType)
266                                                                         , m_format              (pCreateInfo->format)
267                                                                         , m_extent              (pCreateInfo->extent)
268                                                                         , m_samples             (pCreateInfo->samples)
269                                                                 {}
270
271         VkImageType                                     getImageType    (void) const { return m_imageType;      }
272         VkFormat                                        getFormat               (void) const { return m_format;         }
273         VkExtent3D                                      getExtent               (void) const { return m_extent;         }
274         VkSampleCountFlagBits           getSamples              (void) const { return m_samples;        }
275
276 private:
277         const VkImageType                       m_imageType;
278         const VkFormat                          m_format;
279         const VkExtent3D                        m_extent;
280         const VkSampleCountFlagBits     m_samples;
281 };
282
283 class CommandBuffer
284 {
285 public:
286                                                 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
287                                                 {}
288 };
289
290 class DescriptorSet
291 {
292 public:
293         DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
294 };
295
296 class DescriptorPool
297 {
298 public:
299                                                                                 DescriptorPool  (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
300                                                                                         : m_device      (device)
301                                                                                         , m_flags       (pCreateInfo->flags)
302                                                                                 {}
303                                                                                 ~DescriptorPool (void)
304                                                                                 {
305                                                                                         reset();
306                                                                                 }
307
308         VkDescriptorSet                                         allocate                (VkDescriptorSetLayout setLayout);
309         void                                                            free                    (VkDescriptorSet set);
310
311         void                                                            reset                   (void);
312
313 private:
314         const VkDevice                                          m_device;
315         const VkDescriptorPoolCreateFlags       m_flags;
316
317         vector<DescriptorSet*>                          m_managedSets;
318 };
319
320 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
321 {
322         DescriptorSet* const    impl    = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
323
324         try
325         {
326                 m_managedSets.push_back(impl);
327         }
328         catch (...)
329         {
330                 delete impl;
331                 throw;
332         }
333
334         return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
335 }
336
337 void DescriptorPool::free (VkDescriptorSet set)
338 {
339         DescriptorSet* const    impl    = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
340
341         DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
342
343         delete impl;
344
345         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
346         {
347                 if (m_managedSets[ndx] == impl)
348                 {
349                         std::swap(m_managedSets[ndx], m_managedSets.back());
350                         m_managedSets.pop_back();
351                         return;
352                 }
353         }
354
355         DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
356 }
357
358 void DescriptorPool::reset (void)
359 {
360         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
361                 delete m_managedSets[ndx];
362         m_managedSets.clear();
363 }
364
365 // API implementation
366
367 extern "C"
368 {
369
370 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
371 {
372         return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
373 }
374
375 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
376 {
377         return reinterpret_cast<Device*>(device)->getProcAddr(pName);
378 }
379
380 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
381 {
382         deUint32 allocNdx;
383         try
384         {
385                 for (allocNdx = 0; allocNdx < count; allocNdx++)
386                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
387
388                 return VK_SUCCESS;
389         }
390         catch (const std::bad_alloc&)
391         {
392                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
393                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
394
395                 return VK_ERROR_OUT_OF_HOST_MEMORY;
396         }
397         catch (VkResult err)
398         {
399                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
400                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
401
402                 return err;
403         }
404 }
405
406 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
407 {
408         deUint32 allocNdx;
409         try
410         {
411                 for (allocNdx = 0; allocNdx < count; allocNdx++)
412                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
413
414                 return VK_SUCCESS;
415         }
416         catch (const std::bad_alloc&)
417         {
418                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
419                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
420
421                 return VK_ERROR_OUT_OF_HOST_MEMORY;
422         }
423         catch (VkResult err)
424         {
425                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
426                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
427
428                 return err;
429         }
430 }
431
432 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
433 {
434         if (pDevices && *pPhysicalDeviceCount >= 1u)
435                 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
436
437         *pPhysicalDeviceCount = 1;
438
439         return VK_SUCCESS;
440 }
441
442 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
443 {
444         deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
445
446         props->apiVersion               = VK_API_VERSION;
447         props->driverVersion    = 1u;
448         props->deviceType               = VK_PHYSICAL_DEVICE_TYPE_OTHER;
449
450         deMemcpy(props->deviceName, "null", 5);
451
452         // \todo [2015-09-25 pyry] Fill in reasonable limits
453         props->limits.maxTexelBufferElements    = 8096;
454 }
455
456 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
457 {
458         if (props && *count >= 1u)
459         {
460                 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
461
462                 props->queueCount                       = 1u;
463                 props->queueFlags                       = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
464                 props->timestampValidBits       = 64;
465         }
466
467         *count = 1u;
468 }
469
470 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
471 {
472         deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
473
474         props->memoryTypeCount                          = 1u;
475         props->memoryTypes[0].heapIndex         = 0u;
476         props->memoryTypes[0].propertyFlags     = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
477
478         props->memoryHeapCount                          = 1u;
479         props->memoryHeaps[0].size                      = 1ull << 31;
480         props->memoryHeaps[0].flags                     = 0u;
481 }
482
483 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
484 {
485         const VkFormatFeatureFlags      allFeatures     = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
486                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
487                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
488                                                                                         | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
489                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
490                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
491                                                                                         | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
492                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
493                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
494                                                                                         | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
495                                                                                         | VK_FORMAT_FEATURE_BLIT_SRC_BIT
496                                                                                         | VK_FORMAT_FEATURE_BLIT_DST_BIT;
497
498         pFormatProperties->linearTilingFeatures         = allFeatures;
499         pFormatProperties->optimalTilingFeatures        = allFeatures;
500         pFormatProperties->bufferFeatures                       = allFeatures;
501 }
502
503 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
504 {
505         const Buffer*   buffer  = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
506
507         requirements->memoryTypeBits    = 1u;
508         requirements->size                              = buffer->getSize();
509         requirements->alignment                 = (VkDeviceSize)1u;
510 }
511
512 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
513 {
514         return (VkDeviceSize)getPixelSize(mapVkFormat(format))
515                         * (VkDeviceSize)extent.width
516                         * (VkDeviceSize)extent.height
517                         * (VkDeviceSize)extent.depth
518                         * (VkDeviceSize)samples;
519 }
520
521 VkDeviceSize getCompressedImageDataSize (VkFormat format, VkExtent3D extent)
522 {
523         try
524         {
525                 const tcu::CompressedTexFormat  tcuFormat               = mapVkCompressedFormat(format);
526                 const size_t                                    blockSize               = tcu::getBlockSize(tcuFormat);
527                 const tcu::IVec3                                blockPixelSize  = tcu::getBlockPixelSize(tcuFormat);
528                 const int                                               numBlocksX              = deDivRoundUp32((int)extent.width, blockPixelSize.x());
529                 const int                                               numBlocksY              = deDivRoundUp32((int)extent.height, blockPixelSize.y());
530                 const int                                               numBlocksZ              = deDivRoundUp32((int)extent.depth, blockPixelSize.z());
531
532                 return blockSize*numBlocksX*numBlocksY*numBlocksZ;
533         }
534         catch (...)
535         {
536                 return 0; // Unsupported compressed format
537         }
538 }
539
540 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
541 {
542         const Image*    image   = reinterpret_cast<const Image*>(imageHandle.getInternal());
543
544         requirements->memoryTypeBits    = 1u;
545         requirements->alignment                 = 16u;
546
547         if (isCompressedFormat(image->getFormat()))
548                 requirements->size = getCompressedImageDataSize(image->getFormat(), image->getExtent());
549         else
550                 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
551 }
552
553 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
554 {
555         const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
556
557         DE_UNREF(size);
558         DE_UNREF(flags);
559
560         *ppData = (deUint8*)memory->getPtr() + offset;
561
562         return VK_SUCCESS;
563 }
564
565 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
566 {
567         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
568
569         for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
570         {
571                 try
572                 {
573                         pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
574                 }
575                 catch (const std::bad_alloc&)
576                 {
577                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
578                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
579
580                         return VK_ERROR_OUT_OF_HOST_MEMORY;
581                 }
582                 catch (VkResult res)
583                 {
584                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
585                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
586
587                         return res;
588                 }
589         }
590
591         return VK_SUCCESS;
592 }
593
594 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
595 {
596         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
597
598         for (deUint32 ndx = 0; ndx < count; ++ndx)
599                 poolImpl->free(pDescriptorSets[ndx]);
600 }
601
602 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
603 {
604         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
605
606         poolImpl->reset();
607
608         return VK_SUCCESS;
609 }
610
611 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
612 {
613         if (pAllocateInfo && pCommandBuffers)
614         {
615                 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
616                 {
617                         pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
618                 }
619         }
620
621         return VK_SUCCESS;
622 }
623
624 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
625 {
626         DE_UNREF(device);
627         DE_UNREF(commandPool);
628
629         for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
630                 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
631 }
632
633 #include "vkNullDriverImpl.inl"
634
635 } // extern "C"
636
637 Instance::Instance (const VkInstanceCreateInfo*)
638         : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
639 {
640 }
641
642 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
643         : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
644 {
645 }
646
647 class NullDriverLibrary : public Library
648 {
649 public:
650                                                                                 NullDriverLibrary (void)
651                                                                                         : m_library     (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
652                                                                                         , m_driver      (m_library)
653                                                                                 {}
654
655         const PlatformInterface&                        getPlatformInterface    (void) const { return m_driver; }
656
657 private:
658         const tcu::StaticFunctionLibrary        m_library;
659         const PlatformDriver                            m_driver;
660 };
661
662 } // anonymous
663
664 Library* createNullDriver (void)
665 {
666         return new NullDriverLibrary();
667 }
668
669 } // vk