Merge vulkan-cts-1.0 into vulkan-cts-1.0-dev
[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 SurfaceKHR
185 {
186 public:
187                                                                                 SurfaceKHR              (VkInstance, const VkXlibSurfaceCreateInfoKHR*)         {}
188                                                                                 SurfaceKHR              (VkInstance, const VkXcbSurfaceCreateInfoKHR*)          {}
189                                                                                 SurfaceKHR              (VkInstance, const VkWaylandSurfaceCreateInfoKHR*)      {}
190                                                                                 SurfaceKHR              (VkInstance, const VkMirSurfaceCreateInfoKHR*)          {}
191                                                                                 SurfaceKHR              (VkInstance, const VkAndroidSurfaceCreateInfoKHR*)      {}
192                                                                                 SurfaceKHR              (VkInstance, const VkWin32SurfaceCreateInfoKHR*)        {}
193                                                                                 SurfaceKHR              (VkInstance, const VkDisplaySurfaceCreateInfoKHR*)      {}
194                                                                                 ~SurfaceKHR             (void) {}
195 };
196
197 class DisplayModeKHR
198 {
199 public:
200                                                                                 DisplayModeKHR  (VkDisplayKHR, const VkDisplayModeCreateInfoKHR*) {}
201                                                                                 ~DisplayModeKHR (void) {}
202 };
203
204 class DebugReportCallbackEXT
205 {
206 public:
207                                                                                 DebugReportCallbackEXT  (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {}
208                                                                                 ~DebugReportCallbackEXT (void) {}
209 };
210
211 class Device
212 {
213 public:
214                                                                                 Device                  (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
215                                                                                 ~Device                 (void) {}
216
217         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
218
219 private:
220         const tcu::StaticFunctionLibrary        m_functions;
221 };
222
223 class Pipeline
224 {
225 public:
226         Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
227         Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
228 };
229
230 class SwapchainKHR
231 {
232 public:
233                                                                                 SwapchainKHR    (VkDevice, const VkSwapchainCreateInfoKHR*) {}
234                                                                                 ~SwapchainKHR   (void) {}
235 };
236
237 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
238 {
239         // \todo [2015-12-03 pyry] Alignment requirements?
240         // \todo [2015-12-03 pyry] Empty allocations okay?
241         if (pAllocInfo->allocationSize > 0)
242         {
243                 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
244                 if (!heapPtr)
245                         throw std::bad_alloc();
246                 return heapPtr;
247         }
248         else
249                 return DE_NULL;
250 }
251
252 void freeHeap (void* ptr)
253 {
254         deFree(ptr);
255 }
256
257 class DeviceMemory
258 {
259 public:
260                                                 DeviceMemory    (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
261                                                         : m_memory(allocateHeap(pAllocInfo))
262                                                 {
263                                                 }
264                                                 ~DeviceMemory   (void)
265                                                 {
266                                                         freeHeap(m_memory);
267                                                 }
268
269         void*                           getPtr                  (void) const { return m_memory; }
270
271 private:
272         void* const                     m_memory;
273 };
274
275 class Buffer
276 {
277 public:
278                                                 Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
279                                                         : m_size(pCreateInfo->size)
280                                                 {}
281
282         VkDeviceSize            getSize         (void) const { return m_size;   }
283
284 private:
285         const VkDeviceSize      m_size;
286 };
287
288 class Image
289 {
290 public:
291                                                                 Image                   (VkDevice, const VkImageCreateInfo* pCreateInfo)
292                                                                         : m_imageType   (pCreateInfo->imageType)
293                                                                         , m_format              (pCreateInfo->format)
294                                                                         , m_extent              (pCreateInfo->extent)
295                                                                         , m_samples             (pCreateInfo->samples)
296                                                                 {}
297
298         VkImageType                                     getImageType    (void) const { return m_imageType;      }
299         VkFormat                                        getFormat               (void) const { return m_format;         }
300         VkExtent3D                                      getExtent               (void) const { return m_extent;         }
301         VkSampleCountFlagBits           getSamples              (void) const { return m_samples;        }
302
303 private:
304         const VkImageType                       m_imageType;
305         const VkFormat                          m_format;
306         const VkExtent3D                        m_extent;
307         const VkSampleCountFlagBits     m_samples;
308 };
309
310 class CommandBuffer
311 {
312 public:
313                                                 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
314                                                 {}
315 };
316
317 class DescriptorSet
318 {
319 public:
320         DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
321 };
322
323 class DescriptorPool
324 {
325 public:
326                                                                                 DescriptorPool  (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
327                                                                                         : m_device      (device)
328                                                                                         , m_flags       (pCreateInfo->flags)
329                                                                                 {}
330                                                                                 ~DescriptorPool (void)
331                                                                                 {
332                                                                                         reset();
333                                                                                 }
334
335         VkDescriptorSet                                         allocate                (VkDescriptorSetLayout setLayout);
336         void                                                            free                    (VkDescriptorSet set);
337
338         void                                                            reset                   (void);
339
340 private:
341         const VkDevice                                          m_device;
342         const VkDescriptorPoolCreateFlags       m_flags;
343
344         vector<DescriptorSet*>                          m_managedSets;
345 };
346
347 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
348 {
349         DescriptorSet* const    impl    = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
350
351         try
352         {
353                 m_managedSets.push_back(impl);
354         }
355         catch (...)
356         {
357                 delete impl;
358                 throw;
359         }
360
361         return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
362 }
363
364 void DescriptorPool::free (VkDescriptorSet set)
365 {
366         DescriptorSet* const    impl    = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
367
368         DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
369
370         delete impl;
371
372         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
373         {
374                 if (m_managedSets[ndx] == impl)
375                 {
376                         std::swap(m_managedSets[ndx], m_managedSets.back());
377                         m_managedSets.pop_back();
378                         return;
379                 }
380         }
381
382         DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
383 }
384
385 void DescriptorPool::reset (void)
386 {
387         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
388                 delete m_managedSets[ndx];
389         m_managedSets.clear();
390 }
391
392 // API implementation
393
394 extern "C"
395 {
396
397 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
398 {
399         return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
400 }
401
402 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
403 {
404         return reinterpret_cast<Device*>(device)->getProcAddr(pName);
405 }
406
407 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
408 {
409         deUint32 allocNdx;
410         try
411         {
412                 for (allocNdx = 0; allocNdx < count; allocNdx++)
413                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
414
415                 return VK_SUCCESS;
416         }
417         catch (const std::bad_alloc&)
418         {
419                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
420                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
421
422                 return VK_ERROR_OUT_OF_HOST_MEMORY;
423         }
424         catch (VkResult err)
425         {
426                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
427                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
428
429                 return err;
430         }
431 }
432
433 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
434 {
435         deUint32 allocNdx;
436         try
437         {
438                 for (allocNdx = 0; allocNdx < count; allocNdx++)
439                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
440
441                 return VK_SUCCESS;
442         }
443         catch (const std::bad_alloc&)
444         {
445                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
446                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
447
448                 return VK_ERROR_OUT_OF_HOST_MEMORY;
449         }
450         catch (VkResult err)
451         {
452                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
453                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
454
455                 return err;
456         }
457 }
458
459 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
460 {
461         if (pDevices && *pPhysicalDeviceCount >= 1u)
462                 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
463
464         *pPhysicalDeviceCount = 1;
465
466         return VK_SUCCESS;
467 }
468
469 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
470 {
471         deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
472
473         props->apiVersion               = VK_API_VERSION;
474         props->driverVersion    = 1u;
475         props->deviceType               = VK_PHYSICAL_DEVICE_TYPE_OTHER;
476
477         deMemcpy(props->deviceName, "null", 5);
478
479         // \todo [2015-09-25 pyry] Fill in reasonable limits
480         props->limits.maxTexelBufferElements    = 8096;
481 }
482
483 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
484 {
485         if (props && *count >= 1u)
486         {
487                 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
488
489                 props->queueCount                       = 1u;
490                 props->queueFlags                       = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
491                 props->timestampValidBits       = 64;
492         }
493
494         *count = 1u;
495 }
496
497 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
498 {
499         deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
500
501         props->memoryTypeCount                          = 1u;
502         props->memoryTypes[0].heapIndex         = 0u;
503         props->memoryTypes[0].propertyFlags     = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
504
505         props->memoryHeapCount                          = 1u;
506         props->memoryHeaps[0].size                      = 1ull << 31;
507         props->memoryHeaps[0].flags                     = 0u;
508 }
509
510 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
511 {
512         const VkFormatFeatureFlags      allFeatures     = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
513                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
514                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
515                                                                                         | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
516                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
517                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
518                                                                                         | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
519                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
520                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
521                                                                                         | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
522                                                                                         | VK_FORMAT_FEATURE_BLIT_SRC_BIT
523                                                                                         | VK_FORMAT_FEATURE_BLIT_DST_BIT;
524
525         pFormatProperties->linearTilingFeatures         = allFeatures;
526         pFormatProperties->optimalTilingFeatures        = allFeatures;
527         pFormatProperties->bufferFeatures                       = allFeatures;
528 }
529
530 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
531 {
532         const Buffer*   buffer  = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
533
534         requirements->memoryTypeBits    = 1u;
535         requirements->size                              = buffer->getSize();
536         requirements->alignment                 = (VkDeviceSize)1u;
537 }
538
539 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
540 {
541         return (VkDeviceSize)getPixelSize(mapVkFormat(format))
542                         * (VkDeviceSize)extent.width
543                         * (VkDeviceSize)extent.height
544                         * (VkDeviceSize)extent.depth
545                         * (VkDeviceSize)samples;
546 }
547
548 VkDeviceSize getCompressedImageDataSize (VkFormat format, VkExtent3D extent)
549 {
550         try
551         {
552                 const tcu::CompressedTexFormat  tcuFormat               = mapVkCompressedFormat(format);
553                 const size_t                                    blockSize               = tcu::getBlockSize(tcuFormat);
554                 const tcu::IVec3                                blockPixelSize  = tcu::getBlockPixelSize(tcuFormat);
555                 const int                                               numBlocksX              = deDivRoundUp32((int)extent.width, blockPixelSize.x());
556                 const int                                               numBlocksY              = deDivRoundUp32((int)extent.height, blockPixelSize.y());
557                 const int                                               numBlocksZ              = deDivRoundUp32((int)extent.depth, blockPixelSize.z());
558
559                 return blockSize*numBlocksX*numBlocksY*numBlocksZ;
560         }
561         catch (...)
562         {
563                 return 0; // Unsupported compressed format
564         }
565 }
566
567 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
568 {
569         const Image*    image   = reinterpret_cast<const Image*>(imageHandle.getInternal());
570
571         requirements->memoryTypeBits    = 1u;
572         requirements->alignment                 = 16u;
573
574         if (isCompressedFormat(image->getFormat()))
575                 requirements->size = getCompressedImageDataSize(image->getFormat(), image->getExtent());
576         else
577                 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
578 }
579
580 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
581 {
582         const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
583
584         DE_UNREF(size);
585         DE_UNREF(flags);
586
587         *ppData = (deUint8*)memory->getPtr() + offset;
588
589         return VK_SUCCESS;
590 }
591
592 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
593 {
594         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
595
596         for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
597         {
598                 try
599                 {
600                         pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
601                 }
602                 catch (const std::bad_alloc&)
603                 {
604                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
605                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
606
607                         return VK_ERROR_OUT_OF_HOST_MEMORY;
608                 }
609                 catch (VkResult res)
610                 {
611                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
612                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
613
614                         return res;
615                 }
616         }
617
618         return VK_SUCCESS;
619 }
620
621 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
622 {
623         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
624
625         for (deUint32 ndx = 0; ndx < count; ++ndx)
626                 poolImpl->free(pDescriptorSets[ndx]);
627 }
628
629 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
630 {
631         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
632
633         poolImpl->reset();
634
635         return VK_SUCCESS;
636 }
637
638 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
639 {
640         if (pAllocateInfo && pCommandBuffers)
641         {
642                 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
643                 {
644                         pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
645                 }
646         }
647
648         return VK_SUCCESS;
649 }
650
651 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
652 {
653         DE_UNREF(device);
654         DE_UNREF(commandPool);
655
656         for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
657                 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
658 }
659
660
661 VKAPI_ATTR VkResult VKAPI_CALL createDisplayModeKHR (VkPhysicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode)
662 {
663         DE_UNREF(pAllocator);
664         VK_NULL_RETURN((*pMode = allocateNonDispHandle<DisplayModeKHR, VkDisplayModeKHR>(display, pCreateInfo, pAllocator)));
665 }
666
667 VKAPI_ATTR VkResult VKAPI_CALL createSharedSwapchainsKHR (VkDevice device, deUint32 swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains)
668 {
669         for (deUint32 ndx = 0; ndx < swapchainCount; ++ndx)
670         {
671                 pSwapchains[ndx] = allocateNonDispHandle<SwapchainKHR, VkSwapchainKHR>(device, pCreateInfos+ndx, pAllocator);
672         }
673
674         return VK_SUCCESS;
675 }
676
677 #include "vkNullDriverImpl.inl"
678
679 } // extern "C"
680
681 Instance::Instance (const VkInstanceCreateInfo*)
682         : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
683 {
684 }
685
686 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
687         : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
688 {
689 }
690
691 class NullDriverLibrary : public Library
692 {
693 public:
694                                                                                 NullDriverLibrary (void)
695                                                                                         : m_library     (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
696                                                                                         , m_driver      (m_library)
697                                                                                 {}
698
699         const PlatformInterface&                        getPlatformInterface    (void) const { return m_driver; }
700
701 private:
702         const tcu::StaticFunctionLibrary        m_library;
703         const PlatformDriver                            m_driver;
704 };
705
706 } // anonymous
707
708 Library* createNullDriver (void)
709 {
710         return new NullDriverLibrary();
711 }
712
713 } // vk