Merge branch '274-remove-round' into 'master'
[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 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
25  *
26  *//*!
27  * \file
28  * \brief Null (dummy) Vulkan implementation.
29  *//*--------------------------------------------------------------------*/
30
31 #include "vkNullDriver.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkImageUtil.hpp"
34 #include "tcuFunctionLibrary.hpp"
35 #include "deMemory.h"
36
37 #include <stdexcept>
38 #include <algorithm>
39
40 namespace vk
41 {
42
43 namespace
44 {
45
46 using std::vector;
47
48 // Memory management
49
50 template<typename T>
51 void* allocateSystemMem (const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope scope)
52 {
53         void* ptr = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(T), sizeof(void*), scope);
54         if (!ptr)
55                 throw std::bad_alloc();
56         return ptr;
57 }
58
59 void freeSystemMem (const VkAllocationCallbacks* pAllocator, void* mem)
60 {
61         pAllocator->pfnFree(pAllocator->pUserData, mem);
62 }
63
64 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
65 Handle allocateHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
66 {
67         Object* obj = DE_NULL;
68
69         if (pAllocator)
70         {
71                 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
72                 try
73                 {
74                         obj = new (mem) Object(parent, pCreateInfo);
75                         DE_ASSERT(obj == mem);
76                 }
77                 catch (...)
78                 {
79                         pAllocator->pfnFree(pAllocator->pUserData, mem);
80                         throw;
81                 }
82         }
83         else
84                 obj = new Object(parent, pCreateInfo);
85
86         return reinterpret_cast<Handle>(obj);
87 }
88
89 template<typename Object, typename Handle, typename CreateInfo>
90 Handle allocateHandle (const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
91 {
92         Object* obj = DE_NULL;
93
94         if (pAllocator)
95         {
96                 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
97                 try
98                 {
99                         obj = new (mem) Object(pCreateInfo);
100                         DE_ASSERT(obj == mem);
101                 }
102                 catch (...)
103                 {
104                         pAllocator->pfnFree(pAllocator->pUserData, mem);
105                         throw;
106                 }
107         }
108         else
109                 obj = new Object(pCreateInfo);
110
111         return reinterpret_cast<Handle>(obj);
112 }
113
114 template<typename Object, typename Handle>
115 void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
116 {
117         Object* obj = reinterpret_cast<Object*>(handle);
118
119         if (pAllocator)
120         {
121                 obj->~Object();
122                 freeSystemMem(pAllocator, reinterpret_cast<void*>(obj));
123         }
124         else
125                 delete obj;
126 }
127
128 template<typename Object, typename Handle, typename CreateInfo>
129 Handle allocateNonDispHandle (VkDevice device, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
130 {
131         Object* const   obj             = allocateHandle<Object, Object*>(device, pCreateInfo, pAllocator);
132         return Handle((deUint64)(deUintptr)obj);
133 }
134
135 template<typename Object, typename Handle>
136 void freeNonDispHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
137 {
138         freeHandle<Object>(reinterpret_cast<Object*>((deUintptr)handle.getInternal()), pAllocator);
139 }
140
141 // Object definitions
142
143 #define VK_NULL_RETURN(STMT)                                    \
144         do {                                                                            \
145                 try {                                                                   \
146                         STMT;                                                           \
147                         return VK_SUCCESS;                                      \
148                 } catch (const std::bad_alloc&) {               \
149                         return VK_ERROR_OUT_OF_HOST_MEMORY;     \
150                 } catch (VkResult res) {                                \
151                         return res;                                                     \
152                 }                                                                               \
153         } while (deGetFalse())
154
155 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar
156 #define VK_NULL_FUNC_ENTRY(NAME, FUNC)  { #NAME, (deFunctionPtr)FUNC }
157
158 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME)                         \
159 struct NAME                                                                                     \
160 {                                                                                                       \
161         NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
162 }
163
164 VK_NULL_DEFINE_DEVICE_OBJ(Fence);
165 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
166 VK_NULL_DEFINE_DEVICE_OBJ(Event);
167 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
168 VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
169 VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
170 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
171 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
172 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
173 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
174 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
175 VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
176 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
177 VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
178
179 class Instance
180 {
181 public:
182                                                                                 Instance                (const VkInstanceCreateInfo* instanceInfo);
183                                                                                 ~Instance               (void) {}
184
185         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
186
187 private:
188         const tcu::StaticFunctionLibrary        m_functions;
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