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 "vkQueryUtil.hpp"
28 #include "tcuFunctionLibrary.hpp"
29 #include "deMemory.h"
30
31 #include <stdexcept>
32 #include <algorithm>
33
34 namespace vk
35 {
36
37 namespace
38 {
39
40 using std::vector;
41
42 // Memory management
43
44 template<typename T>
allocateSystemMem(const VkAllocationCallbacks * pAllocator,VkSystemAllocationScope scope)45 void* allocateSystemMem (const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope scope)
46 {
47 void* ptr = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(T), sizeof(void*), scope);
48 if (!ptr)
49 throw std::bad_alloc();
50 return ptr;
51 }
52
freeSystemMem(const VkAllocationCallbacks * pAllocator,void * mem)53 void freeSystemMem (const VkAllocationCallbacks* pAllocator, void* mem)
54 {
55 pAllocator->pfnFree(pAllocator->pUserData, mem);
56 }
57
58 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
allocateHandle(Parent parent,const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)59 Handle allocateHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
60 {
61 Object* obj = DE_NULL;
62
63 if (pAllocator)
64 {
65 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
66 try
67 {
68 obj = new (mem) Object(parent, pCreateInfo);
69 DE_ASSERT(obj == mem);
70 }
71 catch (...)
72 {
73 pAllocator->pfnFree(pAllocator->pUserData, mem);
74 throw;
75 }
76 }
77 else
78 obj = new Object(parent, pCreateInfo);
79
80 return reinterpret_cast<Handle>(obj);
81 }
82
83 template<typename Object, typename Handle, typename CreateInfo>
allocateHandle(const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)84 Handle allocateHandle (const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
85 {
86 Object* obj = DE_NULL;
87
88 if (pAllocator)
89 {
90 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
91 try
92 {
93 obj = new (mem) Object(pCreateInfo);
94 DE_ASSERT(obj == mem);
95 }
96 catch (...)
97 {
98 pAllocator->pfnFree(pAllocator->pUserData, mem);
99 throw;
100 }
101 }
102 else
103 obj = new Object(pCreateInfo);
104
105 return reinterpret_cast<Handle>(obj);
106 }
107
108 template<typename Object, typename Handle>
freeHandle(Handle handle,const VkAllocationCallbacks * pAllocator)109 void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
110 {
111 Object* obj = reinterpret_cast<Object*>(handle);
112
113 if (pAllocator)
114 {
115 obj->~Object();
116 freeSystemMem(pAllocator, reinterpret_cast<void*>(obj));
117 }
118 else
119 delete obj;
120 }
121
122 template<typename Object, typename Handle, typename Parent, typename CreateInfo>
allocateNonDispHandle(Parent parent,const CreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)123 Handle allocateNonDispHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
124 {
125 Object* const obj = allocateHandle<Object, Object*>(parent, pCreateInfo, pAllocator);
126 return Handle((deUint64)(deUintptr)obj);
127 }
128
129 template<typename Object, typename Handle>
freeNonDispHandle(Handle handle,const VkAllocationCallbacks * pAllocator)130 void freeNonDispHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
131 {
132 freeHandle<Object>(reinterpret_cast<Object*>((deUintptr)handle.getInternal()), pAllocator);
133 }
134
135 // Object definitions
136
137 #define VK_NULL_RETURN(STMT) \
138 do { \
139 try { \
140 STMT; \
141 return VK_SUCCESS; \
142 } catch (const std::bad_alloc&) { \
143 return VK_ERROR_OUT_OF_HOST_MEMORY; \
144 } catch (VkResult res) { \
145 return res; \
146 } \
147 } while (deGetFalse())
148
149 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar
150 #define VK_NULL_FUNC_ENTRY(NAME, FUNC) { #NAME, (deFunctionPtr)FUNC } // NOLINT(FUNC)
151
152 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME) \
153 struct NAME \
154 { \
155 NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
156 }
157
158 VK_NULL_DEFINE_DEVICE_OBJ(Fence);
159 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
160 VK_NULL_DEFINE_DEVICE_OBJ(Event);
161 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
162 VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
163 VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
164 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
165 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
166 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
167 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
168 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
169 VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
170 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
171
172 class Instance
173 {
174 public:
175 Instance (const VkInstanceCreateInfo* instanceInfo);
~Instance(void)176 ~Instance (void) {}
177
getProcAddr(const char * name) const178 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
179
180 private:
181 const tcu::StaticFunctionLibrary m_functions;
182 };
183
184 class SurfaceKHR
185 {
186 public:
SurfaceKHR(VkInstance,const VkXlibSurfaceCreateInfoKHR *)187 SurfaceKHR (VkInstance, const VkXlibSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkXcbSurfaceCreateInfoKHR *)188 SurfaceKHR (VkInstance, const VkXcbSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkWaylandSurfaceCreateInfoKHR *)189 SurfaceKHR (VkInstance, const VkWaylandSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkMirSurfaceCreateInfoKHR *)190 SurfaceKHR (VkInstance, const VkMirSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkAndroidSurfaceCreateInfoKHR *)191 SurfaceKHR (VkInstance, const VkAndroidSurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkWin32SurfaceCreateInfoKHR *)192 SurfaceKHR (VkInstance, const VkWin32SurfaceCreateInfoKHR*) {}
SurfaceKHR(VkInstance,const VkDisplaySurfaceCreateInfoKHR *)193 SurfaceKHR (VkInstance, const VkDisplaySurfaceCreateInfoKHR*) {}
~SurfaceKHR(void)194 ~SurfaceKHR (void) {}
195 };
196
197 class DisplayModeKHR
198 {
199 public:
DisplayModeKHR(VkDisplayKHR,const VkDisplayModeCreateInfoKHR *)200 DisplayModeKHR (VkDisplayKHR, const VkDisplayModeCreateInfoKHR*) {}
~DisplayModeKHR(void)201 ~DisplayModeKHR (void) {}
202 };
203
204 class DebugReportCallbackEXT
205 {
206 public:
DebugReportCallbackEXT(VkInstance,const VkDebugReportCallbackCreateInfoEXT *)207 DebugReportCallbackEXT (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {}
~DebugReportCallbackEXT(void)208 ~DebugReportCallbackEXT (void) {}
209 };
210
211 class Device
212 {
213 public:
214 Device (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo);
~Device(void)215 ~Device (void) {}
216
getProcAddr(const char * name) const217 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); }
218
219 private:
220 const tcu::StaticFunctionLibrary m_functions;
221 };
222
223 class Pipeline
224 {
225 public:
Pipeline(VkDevice,const VkGraphicsPipelineCreateInfo *)226 Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {}
Pipeline(VkDevice,const VkComputePipelineCreateInfo *)227 Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
228 };
229
230 class SwapchainKHR
231 {
232 public:
SwapchainKHR(VkDevice,const VkSwapchainCreateInfoKHR *)233 SwapchainKHR (VkDevice, const VkSwapchainCreateInfoKHR*) {}
~SwapchainKHR(void)234 ~SwapchainKHR (void) {}
235 };
236
237 class SamplerYcbcrConversionKHR
238 {
239 public:
SamplerYcbcrConversionKHR(VkDevice,const VkSamplerYcbcrConversionCreateInfoKHR *)240 SamplerYcbcrConversionKHR (VkDevice, const VkSamplerYcbcrConversionCreateInfoKHR*) {}
241 };
242
allocateHeap(const VkMemoryAllocateInfo * pAllocInfo)243 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
244 {
245 // \todo [2015-12-03 pyry] Alignment requirements?
246 // \todo [2015-12-03 pyry] Empty allocations okay?
247 if (pAllocInfo->allocationSize > 0)
248 {
249 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
250 if (!heapPtr)
251 throw std::bad_alloc();
252 return heapPtr;
253 }
254 else
255 return DE_NULL;
256 }
257
freeHeap(void * ptr)258 void freeHeap (void* ptr)
259 {
260 deFree(ptr);
261 }
262
263 class DeviceMemory
264 {
265 public:
DeviceMemory(VkDevice,const VkMemoryAllocateInfo * pAllocInfo)266 DeviceMemory (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
267 : m_memory(allocateHeap(pAllocInfo))
268 {
269 // \todo [2016-08-03 pyry] In some cases leaving data unintialized would help valgrind analysis,
270 // but currently it mostly hinders it.
271 if (m_memory)
272 deMemset(m_memory, 0xcd, (size_t)pAllocInfo->allocationSize);
273 }
~DeviceMemory(void)274 ~DeviceMemory (void)
275 {
276 freeHeap(m_memory);
277 }
278
getPtr(void) const279 void* getPtr (void) const { return m_memory; }
280
281 private:
282 void* const m_memory;
283 };
284
285 class Buffer
286 {
287 public:
Buffer(VkDevice,const VkBufferCreateInfo * pCreateInfo)288 Buffer (VkDevice, const VkBufferCreateInfo* pCreateInfo)
289 : m_size(pCreateInfo->size)
290 {}
291
getSize(void) const292 VkDeviceSize getSize (void) const { return m_size; }
293
294 private:
295 const VkDeviceSize m_size;
296 };
297
298 class Image
299 {
300 public:
Image(VkDevice,const VkImageCreateInfo * pCreateInfo)301 Image (VkDevice, const VkImageCreateInfo* pCreateInfo)
302 : m_imageType (pCreateInfo->imageType)
303 , m_format (pCreateInfo->format)
304 , m_extent (pCreateInfo->extent)
305 , m_samples (pCreateInfo->samples)
306 {}
307
getImageType(void) const308 VkImageType getImageType (void) const { return m_imageType; }
getFormat(void) const309 VkFormat getFormat (void) const { return m_format; }
getExtent(void) const310 VkExtent3D getExtent (void) const { return m_extent; }
getSamples(void) const311 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
312
313 private:
314 const VkImageType m_imageType;
315 const VkFormat m_format;
316 const VkExtent3D m_extent;
317 const VkSampleCountFlagBits m_samples;
318 };
319
320 class CommandBuffer
321 {
322 public:
CommandBuffer(VkDevice,VkCommandPool,VkCommandBufferLevel)323 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel)
324 {}
325 };
326
327 class DescriptorUpdateTemplateKHR
328 {
329 public:
DescriptorUpdateTemplateKHR(VkDevice,const VkDescriptorUpdateTemplateCreateInfoKHR *)330 DescriptorUpdateTemplateKHR (VkDevice, const VkDescriptorUpdateTemplateCreateInfoKHR*) {}
331 };
332
333
334 class CommandPool
335 {
336 public:
CommandPool(VkDevice device,const VkCommandPoolCreateInfo *)337 CommandPool (VkDevice device, const VkCommandPoolCreateInfo*)
338 : m_device(device)
339 {}
340 ~CommandPool (void);
341
342 VkCommandBuffer allocate (VkCommandBufferLevel level);
343 void free (VkCommandBuffer buffer);
344
345 private:
346 const VkDevice m_device;
347
348 vector<CommandBuffer*> m_buffers;
349 };
350
~CommandPool(void)351 CommandPool::~CommandPool (void)
352 {
353 for (size_t ndx = 0; ndx < m_buffers.size(); ++ndx)
354 delete m_buffers[ndx];
355 }
356
allocate(VkCommandBufferLevel level)357 VkCommandBuffer CommandPool::allocate (VkCommandBufferLevel level)
358 {
359 CommandBuffer* const impl = new CommandBuffer(m_device, VkCommandPool(reinterpret_cast<deUintptr>(this)), level);
360
361 try
362 {
363 m_buffers.push_back(impl);
364 }
365 catch (...)
366 {
367 delete impl;
368 throw;
369 }
370
371 return reinterpret_cast<VkCommandBuffer>(impl);
372 }
373
free(VkCommandBuffer buffer)374 void CommandPool::free (VkCommandBuffer buffer)
375 {
376 CommandBuffer* const impl = reinterpret_cast<CommandBuffer*>(buffer);
377
378 for (size_t ndx = 0; ndx < m_buffers.size(); ++ndx)
379 {
380 if (m_buffers[ndx] == impl)
381 {
382 std::swap(m_buffers[ndx], m_buffers.back());
383 m_buffers.pop_back();
384 delete impl;
385 return;
386 }
387 }
388
389 DE_FATAL("VkCommandBuffer not owned by VkCommandPool");
390 }
391
392 class DescriptorSet
393 {
394 public:
DescriptorSet(VkDevice,VkDescriptorPool,VkDescriptorSetLayout)395 DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
396 };
397
398 class DescriptorPool
399 {
400 public:
DescriptorPool(VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo)401 DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
402 : m_device (device)
403 , m_flags (pCreateInfo->flags)
404 {}
~DescriptorPool(void)405 ~DescriptorPool (void)
406 {
407 reset();
408 }
409
410 VkDescriptorSet allocate (VkDescriptorSetLayout setLayout);
411 void free (VkDescriptorSet set);
412
413 void reset (void);
414
415 private:
416 const VkDevice m_device;
417 const VkDescriptorPoolCreateFlags m_flags;
418
419 vector<DescriptorSet*> m_managedSets;
420 };
421
allocate(VkDescriptorSetLayout setLayout)422 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
423 {
424 DescriptorSet* const impl = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
425
426 try
427 {
428 m_managedSets.push_back(impl);
429 }
430 catch (...)
431 {
432 delete impl;
433 throw;
434 }
435
436 return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
437 }
438
free(VkDescriptorSet set)439 void DescriptorPool::free (VkDescriptorSet set)
440 {
441 DescriptorSet* const impl = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
442
443 DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
444 DE_UNREF(m_flags);
445
446 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
447 {
448 if (m_managedSets[ndx] == impl)
449 {
450 std::swap(m_managedSets[ndx], m_managedSets.back());
451 m_managedSets.pop_back();
452 delete impl;
453 return;
454 }
455 }
456
457 DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
458 }
459
reset(void)460 void DescriptorPool::reset (void)
461 {
462 for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
463 delete m_managedSets[ndx];
464 m_managedSets.clear();
465 }
466
467 // API implementation
468
469 extern "C"
470 {
471
getDeviceProcAddr(VkDevice device,const char * pName)472 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName)
473 {
474 return reinterpret_cast<Device*>(device)->getProcAddr(pName);
475 }
476
createGraphicsPipelines(VkDevice device,VkPipelineCache,deUint32 count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)477 VKAPI_ATTR VkResult VKAPI_CALL createGraphicsPipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
478 {
479 deUint32 allocNdx;
480 try
481 {
482 for (allocNdx = 0; allocNdx < count; allocNdx++)
483 pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
484
485 return VK_SUCCESS;
486 }
487 catch (const std::bad_alloc&)
488 {
489 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
490 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
491
492 return VK_ERROR_OUT_OF_HOST_MEMORY;
493 }
494 catch (VkResult err)
495 {
496 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
497 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
498
499 return err;
500 }
501 }
502
createComputePipelines(VkDevice device,VkPipelineCache,deUint32 count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)503 VKAPI_ATTR VkResult VKAPI_CALL createComputePipelines (VkDevice device, VkPipelineCache, deUint32 count, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
504 {
505 deUint32 allocNdx;
506 try
507 {
508 for (allocNdx = 0; allocNdx < count; allocNdx++)
509 pPipelines[allocNdx] = allocateNonDispHandle<Pipeline, VkPipeline>(device, pCreateInfos+allocNdx, pAllocator);
510
511 return VK_SUCCESS;
512 }
513 catch (const std::bad_alloc&)
514 {
515 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
516 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
517
518 return VK_ERROR_OUT_OF_HOST_MEMORY;
519 }
520 catch (VkResult err)
521 {
522 for (deUint32 freeNdx = 0; freeNdx < allocNdx; freeNdx++)
523 freeNonDispHandle<Pipeline, VkPipeline>(pPipelines[freeNdx], pAllocator);
524
525 return err;
526 }
527 }
528
enumeratePhysicalDevices(VkInstance,deUint32 * pPhysicalDeviceCount,VkPhysicalDevice * pDevices)529 VKAPI_ATTR VkResult VKAPI_CALL enumeratePhysicalDevices (VkInstance, deUint32* pPhysicalDeviceCount, VkPhysicalDevice* pDevices)
530 {
531 if (pDevices && *pPhysicalDeviceCount >= 1u)
532 *pDevices = reinterpret_cast<VkPhysicalDevice>((void*)(deUintptr)1u);
533
534 *pPhysicalDeviceCount = 1;
535
536 return VK_SUCCESS;
537 }
538
enumerateExtensions(deUint32 numExtensions,const VkExtensionProperties * extensions,deUint32 * pPropertyCount,VkExtensionProperties * pProperties)539 VkResult enumerateExtensions (deUint32 numExtensions, const VkExtensionProperties* extensions, deUint32* pPropertyCount, VkExtensionProperties* pProperties)
540 {
541 const deUint32 dstSize = pPropertyCount ? *pPropertyCount : 0;
542
543 if (pPropertyCount)
544 *pPropertyCount = numExtensions;
545
546 if (pProperties)
547 {
548 for (deUint32 ndx = 0; ndx < de::min(numExtensions, dstSize); ++ndx)
549 pProperties[ndx] = extensions[ndx];
550
551 if (dstSize < numExtensions)
552 return VK_INCOMPLETE;
553 }
554
555 return VK_SUCCESS;
556 }
557
enumerateInstanceExtensionProperties(const char * pLayerName,deUint32 * pPropertyCount,VkExtensionProperties * pProperties)558 VKAPI_ATTR VkResult VKAPI_CALL enumerateInstanceExtensionProperties (const char* pLayerName, deUint32* pPropertyCount, VkExtensionProperties* pProperties)
559 {
560 static const VkExtensionProperties s_extensions[] =
561 {
562 { "VK_KHR_get_physical_device_properties2", 1u }
563 };
564
565 if (!pLayerName)
566 return enumerateExtensions((deUint32)DE_LENGTH_OF_ARRAY(s_extensions), s_extensions, pPropertyCount, pProperties);
567 else
568 return enumerateExtensions(0, DE_NULL, pPropertyCount, pProperties);
569 }
570
enumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,deUint32 * pPropertyCount,VkExtensionProperties * pProperties)571 VKAPI_ATTR VkResult VKAPI_CALL enumerateDeviceExtensionProperties (VkPhysicalDevice physicalDevice, const char* pLayerName, deUint32* pPropertyCount, VkExtensionProperties* pProperties)
572 {
573 DE_UNREF(physicalDevice);
574
575 static const VkExtensionProperties s_extensions[] =
576 {
577 { "VK_KHR_get_memory_requirements2", 1u },
578 { "VK_KHR_bind_memory2", 1u },
579 { "VK_KHR_sampler_ycbcr_conversion", 1u },
580 };
581
582 if (!pLayerName)
583 return enumerateExtensions((deUint32)DE_LENGTH_OF_ARRAY(s_extensions), s_extensions, pPropertyCount, pProperties);
584 else
585 return enumerateExtensions(0, DE_NULL, pPropertyCount, pProperties);
586 }
587
getPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures * pFeatures)588 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFeatures (VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures)
589 {
590 DE_UNREF(physicalDevice);
591
592 // Enable all features allow as many tests to run as possible
593 pFeatures->robustBufferAccess = VK_TRUE;
594 pFeatures->fullDrawIndexUint32 = VK_TRUE;
595 pFeatures->imageCubeArray = VK_TRUE;
596 pFeatures->independentBlend = VK_TRUE;
597 pFeatures->geometryShader = VK_TRUE;
598 pFeatures->tessellationShader = VK_TRUE;
599 pFeatures->sampleRateShading = VK_TRUE;
600 pFeatures->dualSrcBlend = VK_TRUE;
601 pFeatures->logicOp = VK_TRUE;
602 pFeatures->multiDrawIndirect = VK_TRUE;
603 pFeatures->drawIndirectFirstInstance = VK_TRUE;
604 pFeatures->depthClamp = VK_TRUE;
605 pFeatures->depthBiasClamp = VK_TRUE;
606 pFeatures->fillModeNonSolid = VK_TRUE;
607 pFeatures->depthBounds = VK_TRUE;
608 pFeatures->wideLines = VK_TRUE;
609 pFeatures->largePoints = VK_TRUE;
610 pFeatures->alphaToOne = VK_TRUE;
611 pFeatures->multiViewport = VK_TRUE;
612 pFeatures->samplerAnisotropy = VK_TRUE;
613 pFeatures->textureCompressionETC2 = VK_TRUE;
614 pFeatures->textureCompressionASTC_LDR = VK_TRUE;
615 pFeatures->textureCompressionBC = VK_TRUE;
616 pFeatures->occlusionQueryPrecise = VK_TRUE;
617 pFeatures->pipelineStatisticsQuery = VK_TRUE;
618 pFeatures->vertexPipelineStoresAndAtomics = VK_TRUE;
619 pFeatures->fragmentStoresAndAtomics = VK_TRUE;
620 pFeatures->shaderTessellationAndGeometryPointSize = VK_TRUE;
621 pFeatures->shaderImageGatherExtended = VK_TRUE;
622 pFeatures->shaderStorageImageExtendedFormats = VK_TRUE;
623 pFeatures->shaderStorageImageMultisample = VK_TRUE;
624 pFeatures->shaderStorageImageReadWithoutFormat = VK_TRUE;
625 pFeatures->shaderStorageImageWriteWithoutFormat = VK_TRUE;
626 pFeatures->shaderUniformBufferArrayDynamicIndexing = VK_TRUE;
627 pFeatures->shaderSampledImageArrayDynamicIndexing = VK_TRUE;
628 pFeatures->shaderStorageBufferArrayDynamicIndexing = VK_TRUE;
629 pFeatures->shaderStorageImageArrayDynamicIndexing = VK_TRUE;
630 pFeatures->shaderClipDistance = VK_TRUE;
631 pFeatures->shaderCullDistance = VK_TRUE;
632 pFeatures->shaderFloat64 = VK_TRUE;
633 pFeatures->shaderInt64 = VK_TRUE;
634 pFeatures->shaderInt16 = VK_TRUE;
635 pFeatures->shaderResourceResidency = VK_TRUE;
636 pFeatures->shaderResourceMinLod = VK_TRUE;
637 pFeatures->sparseBinding = VK_TRUE;
638 pFeatures->sparseResidencyBuffer = VK_TRUE;
639 pFeatures->sparseResidencyImage2D = VK_TRUE;
640 pFeatures->sparseResidencyImage3D = VK_TRUE;
641 pFeatures->sparseResidency2Samples = VK_TRUE;
642 pFeatures->sparseResidency4Samples = VK_TRUE;
643 pFeatures->sparseResidency8Samples = VK_TRUE;
644 pFeatures->sparseResidency16Samples = VK_TRUE;
645 pFeatures->sparseResidencyAliased = VK_TRUE;
646 pFeatures->variableMultisampleRate = VK_TRUE;
647 pFeatures->inheritedQueries = VK_TRUE;
648 }
649
getPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,VkPhysicalDeviceFeatures2KHR * pFeatures)650 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFeatures2KHR (VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures)
651 {
652 // Core features
653 getPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
654
655 // VK_KHR_sampler_ycbcr_conversion
656 {
657 VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR* extFeatures = findStructure<VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR>(pFeatures->pNext);
658
659 if (extFeatures)
660 extFeatures->samplerYcbcrConversion = VK_TRUE;
661 }
662 }
663
getPhysicalDeviceProperties(VkPhysicalDevice,VkPhysicalDeviceProperties * props)664 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
665 {
666 deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
667
668 props->apiVersion = VK_API_VERSION;
669 props->driverVersion = 1u;
670 props->deviceType = VK_PHYSICAL_DEVICE_TYPE_OTHER;
671
672 deMemcpy(props->deviceName, "null", 5);
673
674 // Spec minmax
675 props->limits.maxImageDimension1D = 4096;
676 props->limits.maxImageDimension2D = 4096;
677 props->limits.maxImageDimension3D = 256;
678 props->limits.maxImageDimensionCube = 4096;
679 props->limits.maxImageArrayLayers = 256;
680 props->limits.maxTexelBufferElements = 65536;
681 props->limits.maxUniformBufferRange = 16384;
682 props->limits.maxStorageBufferRange = 1u<<27;
683 props->limits.maxPushConstantsSize = 128;
684 props->limits.maxMemoryAllocationCount = 4096;
685 props->limits.maxSamplerAllocationCount = 4000;
686 props->limits.bufferImageGranularity = 131072;
687 props->limits.sparseAddressSpaceSize = 1u<<31;
688 props->limits.maxBoundDescriptorSets = 4;
689 props->limits.maxPerStageDescriptorSamplers = 16;
690 props->limits.maxPerStageDescriptorUniformBuffers = 12;
691 props->limits.maxPerStageDescriptorStorageBuffers = 4;
692 props->limits.maxPerStageDescriptorSampledImages = 16;
693 props->limits.maxPerStageDescriptorStorageImages = 4;
694 props->limits.maxPerStageDescriptorInputAttachments = 4;
695 props->limits.maxPerStageResources = 128;
696 props->limits.maxDescriptorSetSamplers = 96;
697 props->limits.maxDescriptorSetUniformBuffers = 72;
698 props->limits.maxDescriptorSetUniformBuffersDynamic = 8;
699 props->limits.maxDescriptorSetStorageBuffers = 24;
700 props->limits.maxDescriptorSetStorageBuffersDynamic = 4;
701 props->limits.maxDescriptorSetSampledImages = 96;
702 props->limits.maxDescriptorSetStorageImages = 24;
703 props->limits.maxDescriptorSetInputAttachments = 4;
704 props->limits.maxVertexInputAttributes = 16;
705 props->limits.maxVertexInputBindings = 16;
706 props->limits.maxVertexInputAttributeOffset = 2047;
707 props->limits.maxVertexInputBindingStride = 2048;
708 props->limits.maxVertexOutputComponents = 64;
709 props->limits.maxTessellationGenerationLevel = 64;
710 props->limits.maxTessellationPatchSize = 32;
711 props->limits.maxTessellationControlPerVertexInputComponents = 64;
712 props->limits.maxTessellationControlPerVertexOutputComponents = 64;
713 props->limits.maxTessellationControlPerPatchOutputComponents = 120;
714 props->limits.maxTessellationControlTotalOutputComponents = 2048;
715 props->limits.maxTessellationEvaluationInputComponents = 64;
716 props->limits.maxTessellationEvaluationOutputComponents = 64;
717 props->limits.maxGeometryShaderInvocations = 32;
718 props->limits.maxGeometryInputComponents = 64;
719 props->limits.maxGeometryOutputComponents = 64;
720 props->limits.maxGeometryOutputVertices = 256;
721 props->limits.maxGeometryTotalOutputComponents = 1024;
722 props->limits.maxFragmentInputComponents = 64;
723 props->limits.maxFragmentOutputAttachments = 4;
724 props->limits.maxFragmentDualSrcAttachments = 1;
725 props->limits.maxFragmentCombinedOutputResources = 4;
726 props->limits.maxComputeSharedMemorySize = 16384;
727 props->limits.maxComputeWorkGroupCount[0] = 65535;
728 props->limits.maxComputeWorkGroupCount[1] = 65535;
729 props->limits.maxComputeWorkGroupCount[2] = 65535;
730 props->limits.maxComputeWorkGroupInvocations = 128;
731 props->limits.maxComputeWorkGroupSize[0] = 128;
732 props->limits.maxComputeWorkGroupSize[1] = 128;
733 props->limits.maxComputeWorkGroupSize[2] = 128;
734 props->limits.subPixelPrecisionBits = 4;
735 props->limits.subTexelPrecisionBits = 4;
736 props->limits.mipmapPrecisionBits = 4;
737 props->limits.maxDrawIndexedIndexValue = 0xffffffffu;
738 props->limits.maxDrawIndirectCount = (1u<<16) - 1u;
739 props->limits.maxSamplerLodBias = 2.0f;
740 props->limits.maxSamplerAnisotropy = 16.0f;
741 props->limits.maxViewports = 16;
742 props->limits.maxViewportDimensions[0] = 4096;
743 props->limits.maxViewportDimensions[1] = 4096;
744 props->limits.viewportBoundsRange[0] = -8192.f;
745 props->limits.viewportBoundsRange[1] = 8191.f;
746 props->limits.viewportSubPixelBits = 0;
747 props->limits.minMemoryMapAlignment = 64;
748 props->limits.minTexelBufferOffsetAlignment = 256;
749 props->limits.minUniformBufferOffsetAlignment = 256;
750 props->limits.minStorageBufferOffsetAlignment = 256;
751 props->limits.minTexelOffset = -8;
752 props->limits.maxTexelOffset = 7;
753 props->limits.minTexelGatherOffset = -8;
754 props->limits.maxTexelGatherOffset = 7;
755 props->limits.minInterpolationOffset = -0.5f;
756 props->limits.maxInterpolationOffset = 0.5f; // -1ulp
757 props->limits.subPixelInterpolationOffsetBits = 4;
758 props->limits.maxFramebufferWidth = 4096;
759 props->limits.maxFramebufferHeight = 4096;
760 props->limits.maxFramebufferLayers = 256;
761 props->limits.framebufferColorSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
762 props->limits.framebufferDepthSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
763 props->limits.framebufferStencilSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
764 props->limits.framebufferNoAttachmentsSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
765 props->limits.maxColorAttachments = 4;
766 props->limits.sampledImageColorSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
767 props->limits.sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT;
768 props->limits.sampledImageDepthSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
769 props->limits.sampledImageStencilSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
770 props->limits.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
771 props->limits.maxSampleMaskWords = 1;
772 props->limits.timestampComputeAndGraphics = VK_TRUE;
773 props->limits.timestampPeriod = 1.0f;
774 props->limits.maxClipDistances = 8;
775 props->limits.maxCullDistances = 8;
776 props->limits.maxCombinedClipAndCullDistances = 8;
777 props->limits.discreteQueuePriorities = 2;
778 props->limits.pointSizeRange[0] = 1.0f;
779 props->limits.pointSizeRange[1] = 64.0f; // -1ulp
780 props->limits.lineWidthRange[0] = 1.0f;
781 props->limits.lineWidthRange[1] = 8.0f; // -1ulp
782 props->limits.pointSizeGranularity = 1.0f;
783 props->limits.lineWidthGranularity = 1.0f;
784 props->limits.strictLines = 0;
785 props->limits.standardSampleLocations = VK_TRUE;
786 props->limits.optimalBufferCopyOffsetAlignment = 256;
787 props->limits.optimalBufferCopyRowPitchAlignment = 256;
788 props->limits.nonCoherentAtomSize = 128;
789 }
790
791
getPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice,VkPhysicalDeviceProperties2KHR * pProperties)792 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceProperties2KHR (VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2KHR* pProperties)
793 {
794 getPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
795 }
796
getPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice,deUint32 * count,VkQueueFamilyProperties * props)797 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
798 {
799 if (props && *count >= 1u)
800 {
801 deMemset(props, 0, sizeof(VkQueueFamilyProperties));
802
803 props->queueCount = 4u;
804 props->queueFlags = VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT;
805 props->timestampValidBits = 64;
806 }
807
808 *count = 1u;
809 }
810
getPhysicalDeviceMemoryProperties(VkPhysicalDevice,VkPhysicalDeviceMemoryProperties * props)811 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
812 {
813 deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
814
815 props->memoryTypeCount = 1u;
816 props->memoryTypes[0].heapIndex = 0u;
817 props->memoryTypes[0].propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
818 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
819 | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
820
821 props->memoryHeapCount = 1u;
822 props->memoryHeaps[0].size = 1ull << 31;
823 props->memoryHeaps[0].flags = 0u;
824 }
825
getPhysicalDeviceFormatProperties(VkPhysicalDevice,VkFormat format,VkFormatProperties * pFormatProperties)826 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
827 {
828 const VkFormatFeatureFlags allFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
829 | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
830 | VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
831 | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
832 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
833 | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
834 | VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
835 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
836 | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
837 | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
838 | VK_FORMAT_FEATURE_BLIT_SRC_BIT
839 | VK_FORMAT_FEATURE_BLIT_DST_BIT
840 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
841 | VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR
842 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR
843 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR
844 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR
845 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR
846 | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
847
848 pFormatProperties->linearTilingFeatures = allFeatures;
849 pFormatProperties->optimalTilingFeatures = allFeatures;
850 pFormatProperties->bufferFeatures = allFeatures;
851
852 if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
853 pFormatProperties->optimalTilingFeatures |= VK_FORMAT_FEATURE_DISJOINT_BIT_KHR;
854 }
855
getPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags,VkImageFormatProperties * pImageFormatProperties)856 VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceImageFormatProperties (VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
857 {
858 DE_UNREF(physicalDevice);
859 DE_UNREF(format);
860 DE_UNREF(type);
861 DE_UNREF(tiling);
862 DE_UNREF(usage);
863 DE_UNREF(flags);
864
865 pImageFormatProperties->maxArrayLayers = 8;
866 pImageFormatProperties->maxExtent.width = 4096;
867 pImageFormatProperties->maxExtent.height = 4096;
868 pImageFormatProperties->maxExtent.depth = 4096;
869 pImageFormatProperties->maxMipLevels = deLog2Ceil32(4096) + 1;
870 pImageFormatProperties->maxResourceSize = 64u * 1024u * 1024u;
871 pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT;
872
873 return VK_SUCCESS;
874 }
875
getDeviceQueue(VkDevice device,deUint32 queueFamilyIndex,deUint32 queueIndex,VkQueue * pQueue)876 VKAPI_ATTR void VKAPI_CALL getDeviceQueue (VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex, VkQueue* pQueue)
877 {
878 DE_UNREF(device);
879 DE_UNREF(queueFamilyIndex);
880
881 if (pQueue)
882 *pQueue = reinterpret_cast<VkQueue>((deUint64)queueIndex + 1);
883 }
884
getBufferMemoryRequirements(VkDevice,VkBuffer bufferHandle,VkMemoryRequirements * requirements)885 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
886 {
887 const Buffer* buffer = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
888
889 requirements->memoryTypeBits = 1u;
890 requirements->size = buffer->getSize();
891 requirements->alignment = (VkDeviceSize)1u;
892 }
893
getBufferMemoryRequirements2KHR(VkDevice device,const VkBufferMemoryRequirementsInfo2KHR * pInfo,VkMemoryRequirements2KHR * pMemoryRequirements)894 VKAPI_ATTR void VKAPI_CALL getBufferMemoryRequirements2KHR (VkDevice device, const VkBufferMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements)
895 {
896 getBufferMemoryRequirements(device, pInfo->buffer, &pMemoryRequirements->memoryRequirements);
897 }
898
getPackedImageDataSize(VkFormat format,VkExtent3D extent,VkSampleCountFlagBits samples)899 VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
900 {
901 return (VkDeviceSize)getPixelSize(mapVkFormat(format))
902 * (VkDeviceSize)extent.width
903 * (VkDeviceSize)extent.height
904 * (VkDeviceSize)extent.depth
905 * (VkDeviceSize)samples;
906 }
907
getCompressedImageDataSize(VkFormat format,VkExtent3D extent)908 VkDeviceSize getCompressedImageDataSize (VkFormat format, VkExtent3D extent)
909 {
910 try
911 {
912 const tcu::CompressedTexFormat tcuFormat = mapVkCompressedFormat(format);
913 const size_t blockSize = tcu::getBlockSize(tcuFormat);
914 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(tcuFormat);
915 const int numBlocksX = deDivRoundUp32((int)extent.width, blockPixelSize.x());
916 const int numBlocksY = deDivRoundUp32((int)extent.height, blockPixelSize.y());
917 const int numBlocksZ = deDivRoundUp32((int)extent.depth, blockPixelSize.z());
918
919 return blockSize*numBlocksX*numBlocksY*numBlocksZ;
920 }
921 catch (...)
922 {
923 return 0; // Unsupported compressed format
924 }
925 }
926
getYCbCrImageDataSize(VkFormat format,VkExtent3D extent)927 VkDeviceSize getYCbCrImageDataSize (VkFormat format, VkExtent3D extent)
928 {
929 const PlanarFormatDescription desc = getPlanarFormatDescription(format);
930 VkDeviceSize totalSize = 0;
931
932 DE_ASSERT(extent.depth == 1);
933
934 for (deUint32 planeNdx = 0; planeNdx < desc.numPlanes; ++planeNdx)
935 {
936 const deUint32 planeW = extent.width / desc.planes[planeNdx].widthDivisor;
937 const deUint32 planeH = extent.height / desc.planes[planeNdx].heightDivisor;
938 const deUint32 elementSize = desc.planes[planeNdx].elementSizeBytes;
939
940 totalSize = (VkDeviceSize)deAlign64((deInt64)totalSize, elementSize);
941 totalSize += planeW * planeH * elementSize;
942 }
943
944 return totalSize;
945 }
946
getImageMemoryRequirements(VkDevice,VkImage imageHandle,VkMemoryRequirements * requirements)947 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
948 {
949 const Image* image = reinterpret_cast<const Image*>(imageHandle.getInternal());
950
951 requirements->memoryTypeBits = 1u;
952 requirements->alignment = 16u;
953
954 if (isCompressedFormat(image->getFormat()))
955 requirements->size = getCompressedImageDataSize(image->getFormat(), image->getExtent());
956 else if (isYCbCrFormat(image->getFormat()))
957 requirements->size = getYCbCrImageDataSize(image->getFormat(), image->getExtent());
958 else
959 requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
960 }
961
getImageMemoryRequirements2KHR(VkDevice device,const VkImageMemoryRequirementsInfo2KHR * pInfo,VkMemoryRequirements2KHR * pMemoryRequirements)962 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements2KHR (VkDevice device, const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements)
963 {
964 const VkImagePlaneMemoryRequirementsInfoKHR* planeReqs = findStructure<VkImagePlaneMemoryRequirementsInfoKHR>(pInfo->pNext);
965
966 if (planeReqs)
967 {
968 const deUint32 planeNdx = getAspectPlaneNdx(planeReqs->planeAspect);
969 const Image* image = reinterpret_cast<const Image*>(pInfo->image.getInternal());
970 const VkFormat format = image->getFormat();
971 const PlanarFormatDescription formatDesc = getPlanarFormatDescription(format);
972
973 DE_ASSERT(de::inBounds<deUint32>(planeNdx, 0u, formatDesc.numPlanes));
974
975 const VkExtent3D extent = image->getExtent();
976 const deUint32 planeW = extent.width / formatDesc.planes[planeNdx].widthDivisor;
977 const deUint32 planeH = extent.height / formatDesc.planes[planeNdx].heightDivisor;
978 const deUint32 elementSize = formatDesc.planes[planeNdx].elementSizeBytes;
979
980 pMemoryRequirements->memoryRequirements.memoryTypeBits = 1u;
981 pMemoryRequirements->memoryRequirements.alignment = 16u;
982 pMemoryRequirements->memoryRequirements.size = planeW * planeH * elementSize;
983 }
984 else
985 getImageMemoryRequirements(device, pInfo->image, &pMemoryRequirements->memoryRequirements);
986 }
987
mapMemory(VkDevice,VkDeviceMemory memHandle,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)988 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
989 {
990 const DeviceMemory* memory = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
991
992 DE_UNREF(size);
993 DE_UNREF(flags);
994
995 *ppData = (deUint8*)memory->getPtr() + offset;
996
997 return VK_SUCCESS;
998 }
999
allocateDescriptorSets(VkDevice,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)1000 VKAPI_ATTR VkResult VKAPI_CALL allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
1001 {
1002 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
1003
1004 for (deUint32 ndx = 0; ndx < pAllocateInfo->descriptorSetCount; ++ndx)
1005 {
1006 try
1007 {
1008 pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
1009 }
1010 catch (const std::bad_alloc&)
1011 {
1012 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
1013 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
1014
1015 return VK_ERROR_OUT_OF_HOST_MEMORY;
1016 }
1017 catch (VkResult res)
1018 {
1019 for (deUint32 freeNdx = 0; freeNdx < ndx; freeNdx++)
1020 delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[freeNdx].getInternal());
1021
1022 return res;
1023 }
1024 }
1025
1026 return VK_SUCCESS;
1027 }
1028
freeDescriptorSets(VkDevice,VkDescriptorPool descriptorPool,deUint32 count,const VkDescriptorSet * pDescriptorSets)1029 VKAPI_ATTR void VKAPI_CALL freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
1030 {
1031 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
1032
1033 for (deUint32 ndx = 0; ndx < count; ++ndx)
1034 poolImpl->free(pDescriptorSets[ndx]);
1035 }
1036
resetDescriptorPool(VkDevice,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags)1037 VKAPI_ATTR VkResult VKAPI_CALL resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
1038 {
1039 DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
1040
1041 poolImpl->reset();
1042
1043 return VK_SUCCESS;
1044 }
1045
allocateCommandBuffers(VkDevice device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)1046 VKAPI_ATTR VkResult VKAPI_CALL allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
1047 {
1048 DE_UNREF(device);
1049
1050 if (pAllocateInfo && pCommandBuffers)
1051 {
1052 CommandPool* const poolImpl = reinterpret_cast<CommandPool*>((deUintptr)pAllocateInfo->commandPool.getInternal());
1053
1054 for (deUint32 ndx = 0; ndx < pAllocateInfo->commandBufferCount; ++ndx)
1055 pCommandBuffers[ndx] = poolImpl->allocate(pAllocateInfo->level);
1056 }
1057
1058 return VK_SUCCESS;
1059 }
1060
freeCommandBuffers(VkDevice device,VkCommandPool commandPool,deUint32 commandBufferCount,const VkCommandBuffer * pCommandBuffers)1061 VKAPI_ATTR void VKAPI_CALL freeCommandBuffers (VkDevice device, VkCommandPool commandPool, deUint32 commandBufferCount, const VkCommandBuffer* pCommandBuffers)
1062 {
1063 CommandPool* const poolImpl = reinterpret_cast<CommandPool*>((deUintptr)commandPool.getInternal());
1064
1065 DE_UNREF(device);
1066
1067 for (deUint32 ndx = 0; ndx < commandBufferCount; ++ndx)
1068 poolImpl->free(pCommandBuffers[ndx]);
1069 }
1070
1071
createDisplayModeKHR(VkPhysicalDevice,VkDisplayKHR display,const VkDisplayModeCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDisplayModeKHR * pMode)1072 VKAPI_ATTR VkResult VKAPI_CALL createDisplayModeKHR (VkPhysicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode)
1073 {
1074 DE_UNREF(pAllocator);
1075 VK_NULL_RETURN((*pMode = allocateNonDispHandle<DisplayModeKHR, VkDisplayModeKHR>(display, pCreateInfo, pAllocator)));
1076 }
1077
createSharedSwapchainsKHR(VkDevice device,deUint32 swapchainCount,const VkSwapchainCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchains)1078 VKAPI_ATTR VkResult VKAPI_CALL createSharedSwapchainsKHR (VkDevice device, deUint32 swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains)
1079 {
1080 for (deUint32 ndx = 0; ndx < swapchainCount; ++ndx)
1081 {
1082 pSwapchains[ndx] = allocateNonDispHandle<SwapchainKHR, VkSwapchainKHR>(device, pCreateInfos+ndx, pAllocator);
1083 }
1084
1085 return VK_SUCCESS;
1086 }
1087
1088 // \note getInstanceProcAddr is a little bit special:
1089 // vkNullDriverImpl.inl needs it to define s_platformFunctions but
1090 // getInstanceProcAddr() implementation needs other entry points from
1091 // vkNullDriverImpl.inl.
1092 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName);
1093
1094 #include "vkNullDriverImpl.inl"
1095
getInstanceProcAddr(VkInstance instance,const char * pName)1096 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName)
1097 {
1098 if (instance)
1099 {
1100 return reinterpret_cast<Instance*>(instance)->getProcAddr(pName);
1101 }
1102 else
1103 {
1104 const std::string name = pName;
1105
1106 if (name == "vkCreateInstance")
1107 return (PFN_vkVoidFunction)createInstance;
1108 else if (name == "vkEnumerateInstanceExtensionProperties")
1109 return (PFN_vkVoidFunction)enumerateInstanceExtensionProperties;
1110 else if (name == "vkEnumerateInstanceLayerProperties")
1111 return (PFN_vkVoidFunction)enumerateInstanceLayerProperties;
1112 else
1113 return (PFN_vkVoidFunction)DE_NULL;
1114 }
1115 }
1116
1117 } // extern "C"
1118
Instance(const VkInstanceCreateInfo *)1119 Instance::Instance (const VkInstanceCreateInfo*)
1120 : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions))
1121 {
1122 }
1123
Device(VkPhysicalDevice,const VkDeviceCreateInfo *)1124 Device::Device (VkPhysicalDevice, const VkDeviceCreateInfo*)
1125 : m_functions(s_deviceFunctions, DE_LENGTH_OF_ARRAY(s_deviceFunctions))
1126 {
1127 }
1128
1129 class NullDriverLibrary : public Library
1130 {
1131 public:
NullDriverLibrary(void)1132 NullDriverLibrary (void)
1133 : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
1134 , m_driver (m_library)
1135 {}
1136
getPlatformInterface(void) const1137 const PlatformInterface& getPlatformInterface (void) const { return m_driver; }
1138
1139 private:
1140 const tcu::StaticFunctionLibrary m_library;
1141 const PlatformDriver m_driver;
1142 };
1143
1144 } // anonymous
1145
createNullDriver(void)1146 Library* createNullDriver (void)
1147 {
1148 return new NullDriverLibrary();
1149 }
1150
1151 } // vk
1152