Test descriptor_update_template, push_descriptor
[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
171 class Instance
172 {
173 public:
174                                                                                 Instance                (const VkInstanceCreateInfo* instanceInfo);
175                                                                                 ~Instance               (void) {}
176
177         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
178
179 private:
180         const tcu::StaticFunctionLibrary        m_functions;
181 };
182
183 class SurfaceKHR
184 {
185 public:
186                                                                                 SurfaceKHR              (VkInstance, const VkXlibSurfaceCreateInfoKHR*)         {}
187                                                                                 SurfaceKHR              (VkInstance, const VkXcbSurfaceCreateInfoKHR*)          {}
188                                                                                 SurfaceKHR              (VkInstance, const VkWaylandSurfaceCreateInfoKHR*)      {}
189                                                                                 SurfaceKHR              (VkInstance, const VkMirSurfaceCreateInfoKHR*)          {}
190                                                                                 SurfaceKHR              (VkInstance, const VkAndroidSurfaceCreateInfoKHR*)      {}
191                                                                                 SurfaceKHR              (VkInstance, const VkWin32SurfaceCreateInfoKHR*)        {}
192                                                                                 SurfaceKHR              (VkInstance, const VkDisplaySurfaceCreateInfoKHR*)      {}
193                                                                                 ~SurfaceKHR             (void) {}
194 };
195
196 class DisplayModeKHR
197 {
198 public:
199                                                                                 DisplayModeKHR  (VkDisplayKHR, const VkDisplayModeCreateInfoKHR*) {}
200                                                                                 ~DisplayModeKHR (void) {}
201 };
202
203 class DebugReportCallbackEXT
204 {
205 public:
206                                                                                 DebugReportCallbackEXT  (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {}
207                                                                                 ~DebugReportCallbackEXT (void) {}
208 };
209
210 class Device
211 {
212 public:
213                                                                                 Device                  (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
214                                                                                 ~Device                 (void) {}
215
216         PFN_vkVoidFunction                                      getProcAddr             (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
217
218 private:
219         const tcu::StaticFunctionLibrary        m_functions;
220 };
221
222 class Pipeline
223 {
224 public:
225         Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
226         Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
227 };
228
229 class SwapchainKHR
230 {
231 public:
232                                                                                 SwapchainKHR    (VkDevice, const VkSwapchainCreateInfoKHR*) {}
233                                                                                 ~SwapchainKHR   (void) {}
234 };
235
236 class IndirectCommandsLayoutNVX
237 {
238 public:
239         IndirectCommandsLayoutNVX (VkDevice, const VkIndirectCommandsLayoutCreateInfoNVX*) {}
240 };
241
242 class ObjectTableNVX
243 {
244 public:
245         ObjectTableNVX (VkDevice, const VkObjectTableCreateInfoNVX*) {}
246 };
247
248 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
249 {
250         // \todo [2015-12-03 pyry] Alignment requirements?
251         // \todo [2015-12-03 pyry] Empty allocations okay?
252         if (pAllocInfo->allocationSize > 0)
253         {
254                 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
255                 if (!heapPtr)
256                         throw std::bad_alloc();
257                 return heapPtr;
258         }
259         else
260                 return DE_NULL;
261 }
262
263 void freeHeap (void* ptr)
264 {
265         deFree(ptr);
266 }
267
268 class DeviceMemory
269 {
270 public:
271                                                 DeviceMemory    (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
272                                                         : m_memory(allocateHeap(pAllocInfo))
273                                                 {
274                                                         // \todo [2016-08-03 pyry] In some cases leaving data unintialized would help valgrind analysis,
275                                                         //                                                 but currently it mostly hinders it.
276                                                         if (m_memory)
277                                                                 deMemset(m_memory, 0xcd, (size_t)pAllocInfo->allocationSize);
278                                                 }
279                                                 ~DeviceMemory   (void)
280                                                 {
281                                                         freeHeap(m_memory);
282                                                 }
283
284         void*                           getPtr                  (void) const { return m_memory; }
285
286 private:
287         void* const                     m_memory;
288 };
289
290 class Buffer
291 {
292 public:
293                                                 Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
294                                                         : m_size(pCreateInfo->size)
295                                                 {}
296
297         VkDeviceSize            getSize         (void) const { return m_size;   }
298
299 private:
300         const VkDeviceSize      m_size;
301 };
302
303 class Image
304 {
305 public:
306                                                                 Image                   (VkDevice, const VkImageCreateInfo* pCreateInfo)
307                                                                         : m_imageType   (pCreateInfo->imageType)
308                                                                         , m_format              (pCreateInfo->format)
309                                                                         , m_extent              (pCreateInfo->extent)
310                                                                         , m_samples             (pCreateInfo->samples)
311                                                                 {}
312
313         VkImageType                                     getImageType    (void) const { return m_imageType;      }
314         VkFormat                                        getFormat               (void) const { return m_format;         }
315         VkExtent3D                                      getExtent               (void) const { return m_extent;         }
316         VkSampleCountFlagBits           getSamples              (void) const { return m_samples;        }
317
318 private:
319         const VkImageType                       m_imageType;
320         const VkFormat                          m_format;
321         const VkExtent3D                        m_extent;
322         const VkSampleCountFlagBits     m_samples;
323 };
324
325 class CommandBuffer
326 {
327 public:
328                                                 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
329                                                 {}
330 };
331
332 class DescriptorUpdateTemplateKHR
333 {
334 public:
335         DescriptorUpdateTemplateKHR (VkDevice, const VkDescriptorUpdateTemplateCreateInfoKHR*) {}
336 };
337
338
339 class CommandPool
340 {
341 public:
342                                                                                 CommandPool             (VkDevice device, const VkCommandPoolCreateInfo*)
343                                                                                         : m_device(device)
344                                                                                 {}
345                                                                                 ~CommandPool    (void);
346
347         VkCommandBuffer                                         allocate                (VkCommandBufferLevel level);
348         void                                                            free                    (VkCommandBuffer buffer);
349
350 private:
351         const VkDevice                                          m_device;
352
353         vector<CommandBuffer*>                          m_buffers;
354 };
355
356 CommandPool::~CommandPool (void)
357 {
358         for (size_t ndx = 0; ndx < m_buffers.size(); ++ndx)
359                 delete m_buffers[ndx];
360 }
361
362 VkCommandBuffer CommandPool::allocate (VkCommandBufferLevel level)
363 {
364         CommandBuffer* const    impl    = new CommandBuffer(m_device, VkCommandPool(reinterpret_cast<deUintptr>(this)), level);
365
366         try
367         {
368                 m_buffers.push_back(impl);
369         }
370         catch (...)
371         {
372                 delete impl;
373                 throw;
374         }
375
376         return reinterpret_cast<VkCommandBuffer>(impl);
377 }
378
379 void CommandPool::free (VkCommandBuffer buffer)
380 {
381         CommandBuffer* const    impl    = reinterpret_cast<CommandBuffer*>(buffer);
382
383         for (size_t ndx = 0; ndx < m_buffers.size(); ++ndx)
384         {
385                 if (m_buffers[ndx] == impl)
386                 {
387                         std::swap(m_buffers[ndx], m_buffers.back());
388                         m_buffers.pop_back();
389                         delete impl;
390                         return;
391                 }
392         }
393
394         DE_FATAL("VkCommandBuffer not owned by VkCommandPool");
395 }
396
397 class DescriptorSet
398 {
399 public:
400         DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
401 };
402
403 class DescriptorPool
404 {
405 public:
406                                                                                 DescriptorPool  (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
407                                                                                         : m_device      (device)
408                                                                                         , m_flags       (pCreateInfo->flags)
409                                                                                 {}
410                                                                                 ~DescriptorPool (void)
411                                                                                 {
412                                                                                         reset();
413                                                                                 }
414
415         VkDescriptorSet                                         allocate                (VkDescriptorSetLayout setLayout);
416         void                                                            free                    (VkDescriptorSet set);
417
418         void                                                            reset                   (void);
419
420 private:
421         const VkDevice                                          m_device;
422         const VkDescriptorPoolCreateFlags       m_flags;
423
424         vector<DescriptorSet*>                          m_managedSets;
425 };
426
427 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
428 {
429         DescriptorSet* const    impl    = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
430
431         try
432         {
433                 m_managedSets.push_back(impl);
434         }
435         catch (...)
436         {
437                 delete impl;
438                 throw;
439         }
440
441         return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
442 }
443
444 void DescriptorPool::free (VkDescriptorSet set)
445 {
446         DescriptorSet* const    impl    = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
447
448         DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
449         DE_UNREF(m_flags);
450
451         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
452         {
453                 if (m_managedSets[ndx] == impl)
454                 {
455                         std::swap(m_managedSets[ndx], m_managedSets.back());
456                         m_managedSets.pop_back();
457                         delete impl;
458                         return;
459                 }
460         }
461
462         DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
463 }
464
465 void DescriptorPool::reset (void)
466 {
467         for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
468                 delete m_managedSets[ndx];
469         m_managedSets.clear();
470 }
471
472 // API implementation
473
474 extern "C"
475 {
476
477 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
478 {
479         return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
480 }
481
482 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
483 {
484         return reinterpret_cast<Device*>(device)->getProcAddr(pName);
485 }
486
487 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
488 {
489         deUint32 allocNdx;
490         try
491         {
492                 for (allocNdx = 0; allocNdx < count; allocNdx++)
493                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
494
495                 return VK_SUCCESS;
496         }
497         catch (const std::bad_alloc&)
498         {
499                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
500                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
501
502                 return VK_ERROR_OUT_OF_HOST_MEMORY;
503         }
504         catch (VkResult err)
505         {
506                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
507                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
508
509                 return err;
510         }
511 }
512
513 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
514 {
515         deUint32 allocNdx;
516         try
517         {
518                 for (allocNdx = 0; allocNdx < count; allocNdx++)
519                         pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
520
521                 return VK_SUCCESS;
522         }
523         catch (const std::bad_alloc&)
524         {
525                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
526                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
527
528                 return VK_ERROR_OUT_OF_HOST_MEMORY;
529         }
530         catch (VkResult err)
531         {
532                 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
533                         freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
534
535                 return err;
536         }
537 }
538
539 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
540 {
541         if (pDevices && *pPhysicalDeviceCount >= 1u)
542                 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
543
544         *pPhysicalDeviceCount = 1;
545
546         return VK_SUCCESS;
547 }
548
549 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFeatures (VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
550 {
551         DE_UNREF(physicalDevice);
552
553         // Enable all features allow as many tests to run as possible
554         pFeatures->robustBufferAccess                                                   = VK_TRUE;
555         pFeatures->fullDrawIndexUint32                                                  = VK_TRUE;
556         pFeatures->imageCubeArray                                                               = VK_TRUE;
557         pFeatures->independentBlend                                                             = VK_TRUE;
558         pFeatures->geometryShader                                                               = VK_TRUE;
559         pFeatures->tessellationShader                                                   = VK_TRUE;
560         pFeatures->sampleRateShading                                                    = VK_TRUE;
561         pFeatures->dualSrcBlend                                                                 = VK_TRUE;
562         pFeatures->logicOp                                                                              = VK_TRUE;
563         pFeatures->multiDrawIndirect                                                    = VK_TRUE;
564         pFeatures->drawIndirectFirstInstance                                    = VK_TRUE;
565         pFeatures->depthClamp                                                                   = VK_TRUE;
566         pFeatures->depthBiasClamp                                                               = VK_TRUE;
567         pFeatures->fillModeNonSolid                                                             = VK_TRUE;
568         pFeatures->depthBounds                                                                  = VK_TRUE;
569         pFeatures->wideLines                                                                    = VK_TRUE;
570         pFeatures->largePoints                                                                  = VK_TRUE;
571         pFeatures->alphaToOne                                                                   = VK_TRUE;
572         pFeatures->multiViewport                                                                = VK_TRUE;
573         pFeatures->samplerAnisotropy                                                    = VK_TRUE;
574         pFeatures->textureCompressionETC2                                               = VK_TRUE;
575         pFeatures->textureCompressionASTC_LDR                                   = VK_TRUE;
576         pFeatures->textureCompressionBC                                                 = VK_TRUE;
577         pFeatures->occlusionQueryPrecise                                                = VK_TRUE;
578         pFeatures->pipelineStatisticsQuery                                              = VK_TRUE;
579         pFeatures->vertexPipelineStoresAndAtomics                               = VK_TRUE;
580         pFeatures->fragmentStoresAndAtomics                                             = VK_TRUE;
581         pFeatures->shaderTessellationAndGeometryPointSize               = VK_TRUE;
582         pFeatures->shaderImageGatherExtended                                    = VK_TRUE;
583         pFeatures->shaderStorageImageExtendedFormats                    = VK_TRUE;
584         pFeatures->shaderStorageImageMultisample                                = VK_TRUE;
585         pFeatures->shaderStorageImageReadWithoutFormat                  = VK_TRUE;
586         pFeatures->shaderStorageImageWriteWithoutFormat                 = VK_TRUE;
587         pFeatures->shaderUniformBufferArrayDynamicIndexing              = VK_TRUE;
588         pFeatures->shaderSampledImageArrayDynamicIndexing               = VK_TRUE;
589         pFeatures->shaderStorageBufferArrayDynamicIndexing              = VK_TRUE;
590         pFeatures->shaderStorageImageArrayDynamicIndexing               = VK_TRUE;
591         pFeatures->shaderClipDistance                                                   = VK_TRUE;
592         pFeatures->shaderCullDistance                                                   = VK_TRUE;
593         pFeatures->shaderFloat64                                                                = VK_TRUE;
594         pFeatures->shaderInt64                                                                  = VK_TRUE;
595         pFeatures->shaderInt16                                                                  = VK_TRUE;
596         pFeatures->shaderResourceResidency                                              = VK_TRUE;
597         pFeatures->shaderResourceMinLod                                                 = VK_TRUE;
598         pFeatures->sparseBinding                                                                = VK_TRUE;
599         pFeatures->sparseResidencyBuffer                                                = VK_TRUE;
600         pFeatures->sparseResidencyImage2D                                               = VK_TRUE;
601         pFeatures->sparseResidencyImage3D                                               = VK_TRUE;
602         pFeatures->sparseResidency2Samples                                              = VK_TRUE;
603         pFeatures->sparseResidency4Samples                                              = VK_TRUE;
604         pFeatures->sparseResidency8Samples                                              = VK_TRUE;
605         pFeatures->sparseResidency16Samples                                             = VK_TRUE;
606         pFeatures->sparseResidencyAliased                                               = VK_TRUE;
607         pFeatures->variableMultisampleRate                                              = VK_TRUE;
608         pFeatures->inheritedQueries                                                             = VK_TRUE;
609 }
610
611 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
612 {
613         deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
614
615         props->apiVersion               = VK_API_VERSION;
616         props->driverVersion    = 1u;
617         props->deviceType               = VK_PHYSICAL_DEVICE_TYPE_OTHER;
618
619         deMemcpy(props->deviceName, "null", 5);
620
621         // Spec minmax
622         props->limits.maxImageDimension1D                                                                       = 4096;
623         props->limits.maxImageDimension2D                                                                       = 4096;
624         props->limits.maxImageDimension3D                                                                       = 256;
625         props->limits.maxImageDimensionCube                                                                     = 4096;
626         props->limits.maxImageArrayLayers                                                                       = 256;
627         props->limits.maxTexelBufferElements                                                            = 65536;
628         props->limits.maxUniformBufferRange                                                                     = 16384;
629         props->limits.maxStorageBufferRange                                                                     = 1u<<27;
630         props->limits.maxPushConstantsSize                                                                      = 128;
631         props->limits.maxMemoryAllocationCount                                                          = 4096;
632         props->limits.maxSamplerAllocationCount                                                         = 4000;
633         props->limits.bufferImageGranularity                                                            = 131072;
634         props->limits.sparseAddressSpaceSize                                                            = 1u<<31;
635         props->limits.maxBoundDescriptorSets                                                            = 4;
636         props->limits.maxPerStageDescriptorSamplers                                                     = 16;
637         props->limits.maxPerStageDescriptorUniformBuffers                                       = 12;
638         props->limits.maxPerStageDescriptorStorageBuffers                                       = 4;
639         props->limits.maxPerStageDescriptorSampledImages                                        = 16;
640         props->limits.maxPerStageDescriptorStorageImages                                        = 4;
641         props->limits.maxPerStageDescriptorInputAttachments                                     = 4;
642         props->limits.maxPerStageResources                                                                      = 128;
643         props->limits.maxDescriptorSetSamplers                                                          = 96;
644         props->limits.maxDescriptorSetUniformBuffers                                            = 72;
645         props->limits.maxDescriptorSetUniformBuffersDynamic                                     = 8;
646         props->limits.maxDescriptorSetStorageBuffers                                            = 24;
647         props->limits.maxDescriptorSetStorageBuffersDynamic                                     = 4;
648         props->limits.maxDescriptorSetSampledImages                                                     = 96;
649         props->limits.maxDescriptorSetStorageImages                                                     = 24;
650         props->limits.maxDescriptorSetInputAttachments                                          = 4;
651         props->limits.maxVertexInputAttributes                                                          = 16;
652         props->limits.maxVertexInputBindings                                                            = 16;
653         props->limits.maxVertexInputAttributeOffset                                                     = 2047;
654         props->limits.maxVertexInputBindingStride                                                       = 2048;
655         props->limits.maxVertexOutputComponents                                                         = 64;
656         props->limits.maxTessellationGenerationLevel                                            = 64;
657         props->limits.maxTessellationPatchSize                                                          = 32;
658         props->limits.maxTessellationControlPerVertexInputComponents            = 64;
659         props->limits.maxTessellationControlPerVertexOutputComponents           = 64;
660         props->limits.maxTessellationControlPerPatchOutputComponents            = 120;
661         props->limits.maxTessellationControlTotalOutputComponents                       = 2048;
662         props->limits.maxTessellationEvaluationInputComponents                          = 64;
663         props->limits.maxTessellationEvaluationOutputComponents                         = 64;
664         props->limits.maxGeometryShaderInvocations                                                      = 32;
665         props->limits.maxGeometryInputComponents                                                        = 64;
666         props->limits.maxGeometryOutputComponents                                                       = 64;
667         props->limits.maxGeometryOutputVertices                                                         = 256;
668         props->limits.maxGeometryTotalOutputComponents                                          = 1024;
669         props->limits.maxFragmentInputComponents                                                        = 64;
670         props->limits.maxFragmentOutputAttachments                                                      = 4;
671         props->limits.maxFragmentDualSrcAttachments                                                     = 1;
672         props->limits.maxFragmentCombinedOutputResources                                        = 4;
673         props->limits.maxComputeSharedMemorySize                                                        = 16384;
674         props->limits.maxComputeWorkGroupCount[0]                                                       = 65535;
675         props->limits.maxComputeWorkGroupCount[1]                                                       = 65535;
676         props->limits.maxComputeWorkGroupCount[2]                                                       = 65535;
677         props->limits.maxComputeWorkGroupInvocations                                            = 128;
678         props->limits.maxComputeWorkGroupSize[0]                                                        = 128;
679         props->limits.maxComputeWorkGroupSize[1]                                                        = 128;
680         props->limits.maxComputeWorkGroupSize[2]                                                        = 128;
681         props->limits.subPixelPrecisionBits                                                                     = 4;
682         props->limits.subTexelPrecisionBits                                                                     = 4;
683         props->limits.mipmapPrecisionBits                                                                       = 4;
684         props->limits.maxDrawIndexedIndexValue                                                          = 0xffffffffu;
685         props->limits.maxDrawIndirectCount                                                                      = (1u<<16) - 1u;
686         props->limits.maxSamplerLodBias                                                                         = 2.0f;
687         props->limits.maxSamplerAnisotropy                                                                      = 16.0f;
688         props->limits.maxViewports                                                                                      = 16;
689         props->limits.maxViewportDimensions[0]                                                          = 4096;
690         props->limits.maxViewportDimensions[1]                                                          = 4096;
691         props->limits.viewportBoundsRange[0]                                                            = -8192.f;
692         props->limits.viewportBoundsRange[1]                                                            = 8191.f;
693         props->limits.viewportSubPixelBits                                                                      = 0;
694         props->limits.minMemoryMapAlignment                                                                     = 64;
695         props->limits.minTexelBufferOffsetAlignment                                                     = 256;
696         props->limits.minUniformBufferOffsetAlignment                                           = 256;
697         props->limits.minStorageBufferOffsetAlignment                                           = 256;
698         props->limits.minTexelOffset                                                                            = -8;
699         props->limits.maxTexelOffset                                                                            = 7;
700         props->limits.minTexelGatherOffset                                                                      = -8;
701         props->limits.maxTexelGatherOffset                                                                      = 7;
702         props->limits.minInterpolationOffset                                                            = -0.5f;
703         props->limits.maxInterpolationOffset                                                            = 0.5f; // -1ulp
704         props->limits.subPixelInterpolationOffsetBits                                           = 4;
705         props->limits.maxFramebufferWidth                                                                       = 4096;
706         props->limits.maxFramebufferHeight                                                                      = 4096;
707         props->limits.maxFramebufferLayers                                                                      = 256;
708         props->limits.framebufferColorSampleCounts                                                      = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
709         props->limits.framebufferDepthSampleCounts                                                      = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
710         props->limits.framebufferStencilSampleCounts                                            = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
711         props->limits.framebufferNoAttachmentsSampleCounts                                      = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
712         props->limits.maxColorAttachments                                                                       = 4;
713         props->limits.sampledImageColorSampleCounts                                                     = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
714         props->limits.sampledImageIntegerSampleCounts                                           = VK_SAMPLE_COUNT_1_BIT;
715         props->limits.sampledImageDepthSampleCounts                                                     = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
716         props->limits.sampledImageStencilSampleCounts                                           = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
717         props->limits.storageImageSampleCounts                                                          = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
718         props->limits.maxSampleMaskWords                                                                        = 1;
719         props->limits.timestampComputeAndGraphics                                                       = VK_TRUE;
720         props->limits.timestampPeriod                                                                           = 1.0f;
721         props->limits.maxClipDistances                                                                          = 8;
722         props->limits.maxCullDistances                                                                          = 8;
723         props->limits.maxCombinedClipAndCullDistances                                           = 8;
724         props->limits.discreteQueuePriorities                                                           = 2;
725         props->limits.pointSizeRange[0]                                                                         = 1.0f;
726         props->limits.pointSizeRange[1]                                                                         = 64.0f; // -1ulp
727         props->limits.lineWidthRange[0]                                                                         = 1.0f;
728         props->limits.lineWidthRange[1]                                                                         = 8.0f; // -1ulp
729         props->limits.pointSizeGranularity                                                                      = 1.0f;
730         props->limits.lineWidthGranularity                                                                      = 1.0f;
731         props->limits.strictLines                                                                                       = 0;
732         props->limits.standardSampleLocations                                                           = VK_TRUE;
733         props->limits.optimalBufferCopyOffsetAlignment                                          = 256;
734         props->limits.optimalBufferCopyRowPitchAlignment                                        = 256;
735         props->limits.nonCoherentAtomSize                                                                       = 128;
736 }
737
738 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
739 {
740         if (props && *count >= 1u)
741         {
742                 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
743
744                 props->queueCount                       = 4u;
745                 props->queueFlags                       = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
746                 props->timestampValidBits       = 64;
747         }
748
749         *count = 1u;
750 }
751
752 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
753 {
754         deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
755
756         props->memoryTypeCount                          = 1u;
757         props->memoryTypes[0].heapIndex         = 0u;
758         props->memoryTypes[0].propertyFlags     = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
759
760         props->memoryHeapCount                          = 1u;
761         props->memoryHeaps[0].size                      = 1ull << 31;
762         props->memoryHeaps[0].flags                     = 0u;
763 }
764
765 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
766 {
767         const VkFormatFeatureFlags      allFeatures     = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
768                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
769                                                                                         | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
770                                                                                         | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
771                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
772                                                                                         | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
773                                                                                         | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
774                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
775                                                                                         | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
776                                                                                         | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
777                                                                                         | VK_FORMAT_FEATURE_BLIT_SRC_BIT
778                                                                                         | VK_FORMAT_FEATURE_BLIT_DST_BIT
779                                                                                         | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
780
781         pFormatProperties->linearTilingFeatures         = allFeatures;
782         pFormatProperties->optimalTilingFeatures        = allFeatures;
783         pFormatProperties->bufferFeatures                       = allFeatures;
784 }
785
786 VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceImageFormatProperties (VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
787 {
788         DE_UNREF(physicalDevice);
789         DE_UNREF(format);
790         DE_UNREF(type);
791         DE_UNREF(tiling);
792         DE_UNREF(usage);
793         DE_UNREF(flags);
794
795         pImageFormatProperties->maxArrayLayers          = 8;
796         pImageFormatProperties->maxExtent.width         = 4096;
797         pImageFormatProperties->maxExtent.height        = 4096;
798         pImageFormatProperties->maxExtent.depth         = 4096;
799         pImageFormatProperties->maxMipLevels            = deLog2Ceil32(4096) + 1;
800         pImageFormatProperties->maxResourceSize         = 64u * 1024u * 1024u;
801         pImageFormatProperties->sampleCounts            = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
802
803         return VK_SUCCESS;
804 }
805
806 VKAPI_ATTR void VKAPI_CALL getDeviceQueue (VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex, VkQueue* pQueue)
807 {
808         DE_UNREF(device);
809         DE_UNREF(queueFamilyIndex);
810
811         if (pQueue)
812                 *pQueue = reinterpret_cast<VkQueue>((deUint64)queueIndex + 1);
813 }
814
815 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
816 {
817         const Buffer*   buffer  = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
818
819         requirements->memoryTypeBits    = 1u;
820         requirements->size                              = buffer->getSize();
821         requirements->alignment                 = (VkDeviceSize)1u;
822 }
823
824 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
825 {
826         return (VkDeviceSize)getPixelSize(mapVkFormat(format))
827                         * (VkDeviceSize)extent.width
828                         * (VkDeviceSize)extent.height
829                         * (VkDeviceSize)extent.depth
830                         * (VkDeviceSize)samples;
831 }
832
833 VkDeviceSize getCompressedImageDataSize (VkFormat format, VkExtent3D extent)
834 {
835         try
836         {
837                 const tcu::CompressedTexFormat  tcuFormat               = mapVkCompressedFormat(format);
838                 const size_t                                    blockSize               = tcu::getBlockSize(tcuFormat);
839                 const tcu::IVec3                                blockPixelSize  = tcu::getBlockPixelSize(tcuFormat);
840                 const int                                               numBlocksX              = deDivRoundUp32((int)extent.width, blockPixelSize.x());
841                 const int                                               numBlocksY              = deDivRoundUp32((int)extent.height, blockPixelSize.y());
842                 const int                                               numBlocksZ              = deDivRoundUp32((int)extent.depth, blockPixelSize.z());
843
844                 return blockSize*numBlocksX*numBlocksY*numBlocksZ;
845         }
846         catch (...)
847         {
848                 return 0; // Unsupported compressed format
849         }
850 }
851
852 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
853 {
854         const Image*    image   = reinterpret_cast<const Image*>(imageHandle.getInternal());
855
856         requirements->memoryTypeBits    = 1u;
857         requirements->alignment                 = 16u;
858
859         if (isCompressedFormat(image->getFormat()))
860                 requirements->size = getCompressedImageDataSize(image->getFormat(), image->getExtent());
861         else
862                 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
863 }
864
865 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
866 {
867         const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
868
869         DE_UNREF(size);
870         DE_UNREF(flags);
871
872         *ppData = (deUint8*)memory->getPtr() + offset;
873
874         return VK_SUCCESS;
875 }
876
877 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
878 {
879         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
880
881         for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
882         {
883                 try
884                 {
885                         pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
886                 }
887                 catch (const std::bad_alloc&)
888                 {
889                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
890                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
891
892                         return VK_ERROR_OUT_OF_HOST_MEMORY;
893                 }
894                 catch (VkResult res)
895                 {
896                         for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
897                                 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
898
899                         return res;
900                 }
901         }
902
903         return VK_SUCCESS;
904 }
905
906 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
907 {
908         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
909
910         for (deUint32 ndx = 0; ndx < count; ++ndx)
911                 poolImpl->free(pDescriptorSets[ndx]);
912 }
913
914 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
915 {
916         DescriptorPool* const   poolImpl        = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
917
918         poolImpl->reset();
919
920         return VK_SUCCESS;
921 }
922
923 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
924 {
925         DE_UNREF(device);
926
927         if (pAllocateInfo && pCommandBuffers)
928         {
929                 CommandPool* const      poolImpl        = reinterpret_cast<CommandPool*>((deUintptr)pAllocateInfo->commandPool.getInternal());
930
931                 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
932                         pCommandBuffers[ndx] = poolImpl->allocate(pAllocateInfo->level);
933         }
934
935         return VK_SUCCESS;
936 }
937
938 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
939 {
940         CommandPool* const      poolImpl        = reinterpret_cast<CommandPool*>((deUintptr)commandPool.getInternal());
941
942         DE_UNREF(device);
943
944         for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
945                 poolImpl->free(pCommandBuffers[ndx]);
946 }
947
948
949 VKAPI_ATTR VkResult VKAPI_CALL createDisplayModeKHR (VkPhysicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode)
950 {
951         DE_UNREF(pAllocator);
952         VK_NULL_RETURN((*pMode = allocateNonDispHandle<DisplayModeKHR, VkDisplayModeKHR>(display, pCreateInfo, pAllocator)));
953 }
954
955 VKAPI_ATTR VkResult VKAPI_CALL createSharedSwapchainsKHR (VkDevice device, deUint32 swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains)
956 {
957         for (deUint32 ndx = 0; ndx < swapchainCount; ++ndx)
958         {
959                 pSwapchains[ndx] = allocateNonDispHandle<SwapchainKHR, VkSwapchainKHR>(device, pCreateInfos+ndx, pAllocator);
960         }
961
962         return VK_SUCCESS;
963 }
964
965 #include "vkNullDriverImpl.inl"
966
967 } // extern "C"
968
969 Instance::Instance (const VkInstanceCreateInfo*)
970         : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
971 {
972 }
973
974 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
975         : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
976 {
977 }
978
979 class NullDriverLibrary : public Library
980 {
981 public:
982                                                                                 NullDriverLibrary (void)
983                                                                                         : m_library     (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
984                                                                                         , m_driver      (m_library)
985                                                                                 {}
986
987         const PlatformInterface&                        getPlatformInterface    (void) const { return m_driver; }
988
989 private:
990         const tcu::StaticFunctionLibrary        m_library;
991         const PlatformDriver                            m_driver;
992 };
993
994 } // anonymous
995
996 Library* createNullDriver (void)
997 {
998         return new NullDriverLibrary();
999 }
1000
1001 } // vk