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>
allocateSystemMem(const VkAllocationCallbacks * pAllocator,VkSystemAllocationScope scope)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
freeSystemMem(const VkAllocationCallbacks * pAllocator,void * mem)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>
allocateHandle(Parent parent,const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)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>
allocateHandle(const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)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>
freeHandle(Handle handle,const VkAllocationCallbacks * pAllocator)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>
allocateNonDispHandle(Parent parent,const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)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>
freeNonDispHandle(Handle handle,const VkAllocationCallbacks * pAllocator)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);
~Instance(void)175 ~Instance (void) {}
176
getProcAddr(const char * name) const177 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:
SurfaceKHR(VkInstance,const VkXlibSurfaceCreateInfoKHR *)186 SurfaceKHR (VkInstance, const VkXlibSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkXcbSurfaceCreateInfoKHR *)187 SurfaceKHR (VkInstance, const VkXcbSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkWaylandSurfaceCreateInfoKHR *)188 SurfaceKHR (VkInstance, const VkWaylandSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkMirSurfaceCreateInfoKHR *)189 SurfaceKHR (VkInstance, const VkMirSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkAndroidSurfaceCreateInfoKHR *)190 SurfaceKHR (VkInstance, const VkAndroidSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkWin32SurfaceCreateInfoKHR *)191 SurfaceKHR (VkInstance, const VkWin32SurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkDisplaySurfaceCreateInfoKHR *)192 SurfaceKHR (VkInstance, const VkDisplaySurfaceCreateInfoKHR*) {}
~SurfaceKHR(void)193 ~SurfaceKHR (void) {}
194 };
195
196 class DisplayModeKHR
197 {
198 public:
DisplayModeKHR(VkDisplayKHR,const VkDisplayModeCreateInfoKHR *)199 DisplayModeKHR (VkDisplayKHR, const VkDisplayModeCreateInfoKHR*) {}
~DisplayModeKHR(void)200 ~DisplayModeKHR (void) {}
201 };
202
203 class DebugReportCallbackEXT
204 {
205 public:
DebugReportCallbackEXT(VkInstance,const VkDebugReportCallbackCreateInfoEXT *)206 DebugReportCallbackEXT (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {}
~DebugReportCallbackEXT(void)207 ~DebugReportCallbackEXT (void) {}
208 };
209
210 class Device
211 {
212 public:
213 Device (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
~Device(void)214 ~Device (void) {}
215
getProcAddr(const char * name) const216 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:
Pipeline(VkDevice,const VkGraphicsPipelineCreateInfo *)225 Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
Pipeline(VkDevice,const VkComputePipelineCreateInfo *)226 Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
227 };
228
229 class SwapchainKHR
230 {
231 public:
SwapchainKHR(VkDevice,const VkSwapchainCreateInfoKHR *)232 SwapchainKHR (VkDevice, const VkSwapchainCreateInfoKHR*) {}
~SwapchainKHR(void)233 ~SwapchainKHR (void) {}
234 };
235
236 class IndirectCommandsLayoutNVX
237 {
238 public:
IndirectCommandsLayoutNVX(VkDevice,const VkIndirectCommandsLayoutCreateInfoNVX *)239 IndirectCommandsLayoutNVX (VkDevice, const VkIndirectCommandsLayoutCreateInfoNVX*) {}
240 };
241
242 class ObjectTableNVX
243 {
244 public:
ObjectTableNVX(VkDevice,const VkObjectTableCreateInfoNVX *)245 ObjectTableNVX (VkDevice, const VkObjectTableCreateInfoNVX*) {}
246 };
247
allocateHeap(const VkMemoryAllocateInfo * pAllocInfo)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
freeHeap(void * ptr)263 void freeHeap (void* ptr)
264 {
265 deFree(ptr);
266 }
267
268 class DeviceMemory
269 {
270 public:
DeviceMemory(VkDevice,const VkMemoryAllocateInfo * pAllocInfo)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 }
~DeviceMemory(void)279 ~DeviceMemory (void)
280 {
281 freeHeap(m_memory);
282 }
283
getPtr(void) const284 void* getPtr (void) const { return m_memory; }
285
286 private:
287 void* const m_memory;
288 };
289
290 class Buffer
291 {
292 public:
Buffer(VkDevice,const VkBufferCreateInfo * pCreateInfo)293 Buffer (VkDevice, const VkBufferCreateInfo* pCreateInfo)
294 : m_size(pCreateInfo->size)
295 {}
296
getSize(void) const297 VkDeviceSize getSize (void) const { return m_size; }
298
299 private:
300 const VkDeviceSize m_size;
301 };
302
303 class Image
304 {
305 public:
Image(VkDevice,const VkImageCreateInfo * pCreateInfo)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
getImageType(void) const313 VkImageType getImageType (void) const { return m_imageType; }
getFormat(void) const314 VkFormat getFormat (void) const { return m_format; }
getExtent(void) const315 VkExtent3D getExtent (void) const { return m_extent; }
getSamples(void) const316 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:
CommandBuffer(VkDevice,VkCommandPool,VkCommandBufferLevel)328 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
329 {}
330 };
331
332 class DescriptorUpdateTemplateKHR
333 {
334 public:
DescriptorUpdateTemplateKHR(VkDevice,const VkDescriptorUpdateTemplateCreateInfoKHR *)335 DescriptorUpdateTemplateKHR (VkDevice, const VkDescriptorUpdateTemplateCreateInfoKHR*) {}
336 };
337
338
339 class CommandPool
340 {
341 public:
CommandPool(VkDevice device,const VkCommandPoolCreateInfo *)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
~CommandPool(void)356 CommandPool::~CommandPool (void)
357 {
358 for (size_t ndx = 0; ndx < m_buffers.size(); ++ndx)
359 delete m_buffers[ndx];
360 }
361
allocate(VkCommandBufferLevel level)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
free(VkCommandBuffer buffer)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:
DescriptorSet(VkDevice,VkDescriptorPool,VkDescriptorSetLayout)400 DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
401 };
402
403 class DescriptorPool
404 {
405 public:
DescriptorPool(VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo)406 DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
407 : m_device (device)
408 , m_flags (pCreateInfo->flags)
409 {}
~DescriptorPool(void)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
allocate(VkDescriptorSetLayout setLayout)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
free(VkDescriptorSet set)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
reset(void)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
getInstanceProcAddr(VkInstance instance,const char * pName)477 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
478 {
479 return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
480 }
481
getDeviceProcAddr(VkDevice device,const char * pName)482 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
483 {
484 return reinterpret_cast<Device*>(device)->getProcAddr(pName);
485 }
486
createGraphicsPipelines(VkDevice device,VkPipelineCache,deUint32 count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)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
createComputePipelines(VkDevice device,VkPipelineCache,deUint32 count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)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
enumeratePhysicalDevices(VkInstance,deUint32 * pPhysicalDeviceCount,VkPhysicalDevice * pDevices)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
getPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)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
getPhysicalDeviceProperties(VkPhysicalDevice,VkPhysicalDeviceProperties * props)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
getPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice,deUint32 * count,VkQueueFamilyProperties * props)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
getPhysicalDeviceMemoryProperties(VkPhysicalDevice,VkPhysicalDeviceMemoryProperties * props)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
getPhysicalDeviceFormatProperties(VkPhysicalDevice,VkFormat,VkFormatProperties * pFormatProperties)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
getPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)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
getDeviceQueue(VkDevice device,deUint32 queueFamilyIndex,deUint32 queueIndex,VkQueue * pQueue)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
getBufferMemoryRequirements(VkDevice,VkBuffer bufferHandle,VkMemoryRequirements * requirements)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
getPackedImageDataSize(VkFormat format,VkExtent3D extent,VkSampleCountFlagBits samples)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
getCompressedImageDataSize(VkFormat format,VkExtent3D extent)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
getImageMemoryRequirements(VkDevice,VkImage imageHandle,VkMemoryRequirements * requirements)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
mapMemory(VkDevice,VkDeviceMemory memHandle,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)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
allocateDescriptorSets(VkDevice,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)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
freeDescriptorSets(VkDevice,VkDescriptorPool descriptorPool,deUint32 count,const VkDescriptorSet * pDescriptorSets)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
resetDescriptorPool(VkDevice,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags)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
allocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)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
freeCommandBuffers(VkDevice device,VkCommandPool commandPool,deUint32 commandBufferCount,const VkCommandBuffer * pCommandBuffers)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
createDisplayModeKHR(VkPhysicalDevice,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDisplayModeKHR * pMode)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
createSharedSwapchainsKHR(VkDevice device,deUint32 swapchainCount,const VkSwapchainCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchains)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
Instance(const VkInstanceCreateInfo *)969 Instance::Instance (const VkInstanceCreateInfo*)
970 : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
971 {
972 }
973
Device(VkPhysicalDevice,const VkDeviceCreateInfo *)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:
NullDriverLibrary(void)982 NullDriverLibrary (void)
983 : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
984 , m_driver (m_library)
985 {}
986
getPlatformInterface(void) const987 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
createNullDriver(void)996 Library* createNullDriver (void)
997 {
998 return new NullDriverLibrary();
999 }
1000
1001 } // vk
1002