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