Fix misc-macro-parentheses warnings in deqp.
[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 }  // NOLINT(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         DE_UNREF(m_flags);
370
371         delete impl;
372
373         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
374         {
375                 if (m_managedSets[ndx] == impl)
376                 {
377                         std::swap(m_managedSets[ndx], m_managedSets.back());
378                         m_managedSets.pop_back();
379                         return;
380                 }
381         }
382
383         DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
384 }
385
386 void DescriptorPool::reset (void)
387 {
388         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
389                 delete m_managedSets[ndx];
390         m_managedSets.clear();
391 }
392
393 // API implementation
394
395 extern "C"
396 {
397
398 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
399 {
400         return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
401 }
402
403 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
404 {
405         return reinterpret_cast<Device*>(device)->getProcAddr(pName);
406 }
407
408 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
409 {
410         deUint32 allocNdx;
411         try
412         {
413                 for (allocNdx = 0; allocNdx < count; allocNdx++)
414                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
415
416                 return VK_SUCCESS;
417         }
418         catch (const std::bad_alloc&)
419         {
420                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
421                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
422
423                 return VK_ERROR_OUT_OF_HOST_MEMORY;
424         }
425         catch (VkResult err)
426         {
427                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
428                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
429
430                 return err;
431         }
432 }
433
434 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
435 {
436         deUint32 allocNdx;
437         try
438         {
439                 for (allocNdx = 0; allocNdx < count; allocNdx++)
440                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
441
442                 return VK_SUCCESS;
443         }
444         catch (const std::bad_alloc&)
445         {
446                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
447                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
448
449                 return VK_ERROR_OUT_OF_HOST_MEMORY;
450         }
451         catch (VkResult err)
452         {
453                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
454                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
455
456                 return err;
457         }
458 }
459
460 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
461 {
462         if (pDevices && *pPhysicalDeviceCount >= 1u)
463                 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
464
465         *pPhysicalDeviceCount = 1;
466
467         return VK_SUCCESS;
468 }
469
470 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
471 {
472         deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
473
474         props->apiVersion               = VK_API_VERSION;
475         props->driverVersion    = 1u;
476         props->deviceType               = VK_PHYSICAL_DEVICE_TYPE_OTHER;
477
478         deMemcpy(props->deviceName, "null", 5);
479
480         // \todo [2015-09-25 pyry] Fill in reasonable limits
481         props->limits.maxTexelBufferElements    = 8096;
482 }
483
484 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
485 {
486         if (props && *count >= 1u)
487         {
488                 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
489
490                 props->queueCount                       = 1u;
491                 props->queueFlags                       = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
492                 props->timestampValidBits       = 64;
493         }
494
495         *count = 1u;
496 }
497
498 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
499 {
500         deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
501
502         props->memoryTypeCount                          = 1u;
503         props->memoryTypes[0].heapIndex         = 0u;
504         props->memoryTypes[0].propertyFlags     = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
505
506         props->memoryHeapCount                          = 1u;
507         props->memoryHeaps[0].size                      = 1ull << 31;
508         props->memoryHeaps[0].flags                     = 0u;
509 }
510
511 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
512 {
513         const VkFormatFeatureFlags      allFeatures     = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
514                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
515                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
516                                                                                         | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
517                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
518                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
519                                                                                         | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
520                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
521                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
522                                                                                         | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
523                                                                                         | VK_FORMAT_FEATURE_BLIT_SRC_BIT
524                                                                                         | VK_FORMAT_FEATURE_BLIT_DST_BIT;
525
526         pFormatProperties->linearTilingFeatures         = allFeatures;
527         pFormatProperties->optimalTilingFeatures        = allFeatures;
528         pFormatProperties->bufferFeatures                       = allFeatures;
529 }
530
531 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
532 {
533         const Buffer*   buffer  = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
534
535         requirements->memoryTypeBits    = 1u;
536         requirements->size                              = buffer->getSize();
537         requirements->alignment                 = (VkDeviceSize)1u;
538 }
539
540 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
541 {
542         return (VkDeviceSize)getPixelSize(mapVkFormat(format))
543                         * (VkDeviceSize)extent.width
544                         * (VkDeviceSize)extent.height
545                         * (VkDeviceSize)extent.depth
546                         * (VkDeviceSize)samples;
547 }
548
549 VkDeviceSize getCompressedImageDataSize (VkFormat format, VkExtent3D extent)
550 {
551         try
552         {
553                 const tcu::CompressedTexFormat  tcuFormat               = mapVkCompressedFormat(format);
554                 const size_t                                    blockSize               = tcu::getBlockSize(tcuFormat);
555                 const tcu::IVec3                                blockPixelSize  = tcu::getBlockPixelSize(tcuFormat);
556                 const int                                               numBlocksX              = deDivRoundUp32((int)extent.width, blockPixelSize.x());
557                 const int                                               numBlocksY              = deDivRoundUp32((int)extent.height, blockPixelSize.y());
558                 const int                                               numBlocksZ              = deDivRoundUp32((int)extent.depth, blockPixelSize.z());
559
560                 return blockSize*numBlocksX*numBlocksY*numBlocksZ;
561         }
562         catch (...)
563         {
564                 return 0; // Unsupported compressed format
565         }
566 }
567
568 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
569 {
570         const Image*    image   = reinterpret_cast<const Image*>(imageHandle.getInternal());
571
572         requirements->memoryTypeBits    = 1u;
573         requirements->alignment                 = 16u;
574
575         if (isCompressedFormat(image->getFormat()))
576                 requirements->size = getCompressedImageDataSize(image->getFormat(), image->getExtent());
577         else
578                 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
579 }
580
581 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
582 {
583         const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
584
585         DE_UNREF(size);
586         DE_UNREF(flags);
587
588         *ppData = (deUint8*)memory->getPtr() + offset;
589
590         return VK_SUCCESS;
591 }
592
593 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
594 {
595         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
596
597         for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
598         {
599                 try
600                 {
601                         pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
602                 }
603                 catch (const std::bad_alloc&)
604                 {
605                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
606                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
607
608                         return VK_ERROR_OUT_OF_HOST_MEMORY;
609                 }
610                 catch (VkResult res)
611                 {
612                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
613                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
614
615                         return res;
616                 }
617         }
618
619         return VK_SUCCESS;
620 }
621
622 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
623 {
624         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
625
626         for (deUint32 ndx = 0; ndx < count; ++ndx)
627                 poolImpl->free(pDescriptorSets[ndx]);
628 }
629
630 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
631 {
632         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
633
634         poolImpl->reset();
635
636         return VK_SUCCESS;
637 }
638
639 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
640 {
641         if (pAllocateInfo && pCommandBuffers)
642         {
643                 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
644                 {
645                         pCommandBuffers[ndx] = reinterpret_cast<VkCommandBuffer>(new CommandBuffer(device, pAllocateInfo->commandPool, pAllocateInfo->level));
646                 }
647         }
648
649         return VK_SUCCESS;
650 }
651
652 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
653 {
654         DE_UNREF(device);
655         DE_UNREF(commandPool);
656
657         for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
658                 delete reinterpret_cast<CommandBuffer*>(pCommandBuffers[ndx]);
659 }
660
661
662 VKAPI_ATTR VkResult VKAPI_CALL createDisplayModeKHR (VkPhysicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode)
663 {
664         DE_UNREF(pAllocator);
665         VK_NULL_RETURN((*pMode = allocateNonDispHandle<DisplayModeKHR, VkDisplayModeKHR>(display, pCreateInfo, pAllocator)));
666 }
667
668 VKAPI_ATTR VkResult VKAPI_CALL createSharedSwapchainsKHR (VkDevice device, deUint32 swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains)
669 {
670         for (deUint32 ndx = 0; ndx < swapchainCount; ++ndx)
671         {
672                 pSwapchains[ndx] = allocateNonDispHandle<SwapchainKHR, VkSwapchainKHR>(device, pCreateInfos+ndx, pAllocator);
673         }
674
675         return VK_SUCCESS;
676 }
677
678 #include "vkNullDriverImpl.inl"
679
680 } // extern "C"
681
682 Instance::Instance (const VkInstanceCreateInfo*)
683         : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
684 {
685 }
686
687 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
688         : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
689 {
690 }
691
692 class NullDriverLibrary : public Library
693 {
694 public:
695                                                                                 NullDriverLibrary (void)
696                                                                                         : m_library     (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
697                                                                                         , m_driver      (m_library)
698                                                                                 {}
699
700         const PlatformInterface&                        getPlatformInterface    (void) const { return m_driver; }
701
702 private:
703         const tcu::StaticFunctionLibrary        m_library;
704         const PlatformDriver                            m_driver;
705 };
706
707 } // anonymous
708
709 Library* createNullDriver (void)
710 {
711         return new NullDriverLibrary();
712 }
713
714 } // vk