1 /*------------------------------------------------------------------------- 2 * Vulkan CTS Framework 3 * -------------------- 4 * 5 * Copyright (c) 2015 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Null (dummy) Vulkan implementation. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vkNullDriver.hpp" 25 #include "vkPlatform.hpp" 26 #include "vkImageUtil.hpp" 27 #include "tcuFunctionLibrary.hpp" 28 #include "deMemory.h" 29 30 #include <stdexcept> 31 #include <algorithm> 32 33 namespace vk 34 { 35 36 namespace 37 { 38 39 using std::vector; 40 41 // Memory management 42 43 template<typename T> 44 void* allocateSystemMem (const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope scope) 45 { 46 void* ptr = pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(T), sizeof(void*), scope); 47 if (!ptr) 48 throw std::bad_alloc(); 49 return ptr; 50 } 51 52 void freeSystemMem (const VkAllocationCallbacks* pAllocator, void* mem) 53 { 54 pAllocator->pfnFree(pAllocator->pUserData, mem); 55 } 56 57 template<typename Object, typename Handle, typename Parent, typename CreateInfo> 58 Handle allocateHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) 59 { 60 Object* obj = DE_NULL; 61 62 if (pAllocator) 63 { 64 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 65 try 66 { 67 obj = new (mem) Object(parent, pCreateInfo); 68 DE_ASSERT(obj == mem); 69 } 70 catch (...) 71 { 72 pAllocator->pfnFree(pAllocator->pUserData, mem); 73 throw; 74 } 75 } 76 else 77 obj = new Object(parent, pCreateInfo); 78 79 return reinterpret_cast<Handle>(obj); 80 } 81 82 template<typename Object, typename Handle, typename CreateInfo> 83 Handle allocateHandle (const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) 84 { 85 Object* obj = DE_NULL; 86 87 if (pAllocator) 88 { 89 void* mem = allocateSystemMem<Object>(pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 90 try 91 { 92 obj = new (mem) Object(pCreateInfo); 93 DE_ASSERT(obj == mem); 94 } 95 catch (...) 96 { 97 pAllocator->pfnFree(pAllocator->pUserData, mem); 98 throw; 99 } 100 } 101 else 102 obj = new Object(pCreateInfo); 103 104 return reinterpret_cast<Handle>(obj); 105 } 106 107 template<typename Object, typename Handle> 108 void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator) 109 { 110 Object* obj = reinterpret_cast<Object*>(handle); 111 112 if (pAllocator) 113 { 114 obj->~Object(); 115 freeSystemMem(pAllocator, reinterpret_cast<void*>(obj)); 116 } 117 else 118 delete obj; 119 } 120 121 template<typename Object, typename Handle, typename Parent, typename CreateInfo> 122 Handle allocateNonDispHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) 123 { 124 Object* const obj = allocateHandle<Object, Object*>(parent, pCreateInfo, pAllocator); 125 return Handle((deUint64)(deUintptr)obj); 126 } 127 128 template<typename Object, typename Handle> 129 void freeNonDispHandle (Handle handle, const VkAllocationCallbacks* pAllocator) 130 { 131 freeHandle<Object>(reinterpret_cast<Object*>((deUintptr)handle.getInternal()), pAllocator); 132 } 133 134 // Object definitions 135 136 #define VK_NULL_RETURN(STMT) \ 137 do { \ 138 try { \ 139 STMT; \ 140 return VK_SUCCESS; \ 141 } catch (const std::bad_alloc&) { \ 142 return VK_ERROR_OUT_OF_HOST_MEMORY; \ 143 } catch (VkResult res) { \ 144 return res; \ 145 } \ 146 } while (deGetFalse()) 147 148 // \todo [2015-07-14 pyry] Check FUNC type by checkedCastToPtr<T>() or similar 149 #define VK_NULL_FUNC_ENTRY(NAME, FUNC) { #NAME, (deFunctionPtr)FUNC } 150 151 #define VK_NULL_DEFINE_DEVICE_OBJ(NAME) \ 152 struct NAME \ 153 { \ 154 NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \ 155 } 156 157 VK_NULL_DEFINE_DEVICE_OBJ(Fence); 158 VK_NULL_DEFINE_DEVICE_OBJ(Semaphore); 159 VK_NULL_DEFINE_DEVICE_OBJ(Event); 160 VK_NULL_DEFINE_DEVICE_OBJ(QueryPool); 161 VK_NULL_DEFINE_DEVICE_OBJ(BufferView); 162 VK_NULL_DEFINE_DEVICE_OBJ(ImageView); 163 VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule); 164 VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache); 165 VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout); 166 VK_NULL_DEFINE_DEVICE_OBJ(RenderPass); 167 VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout); 168 VK_NULL_DEFINE_DEVICE_OBJ(Sampler); 169 VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer); 170 VK_NULL_DEFINE_DEVICE_OBJ(CommandPool); 171 172 class Instance 173 { 174 public: 175 Instance (const VkInstanceCreateInfo* instanceInfo); 176 ~Instance (void) {} 177 178 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); } 179 180 private: 181 const tcu::StaticFunctionLibrary m_functions; 182 }; 183 184 class SurfaceKHR 185 { 186 public: 187 SurfaceKHR (VkInstance, const VkXlibSurfaceCreateInfoKHR*) {} 188 SurfaceKHR (VkInstance, const VkXcbSurfaceCreateInfoKHR*) {} 189 SurfaceKHR (VkInstance, const VkWaylandSurfaceCreateInfoKHR*) {} 190 SurfaceKHR (VkInstance, const VkMirSurfaceCreateInfoKHR*) {} 191 SurfaceKHR (VkInstance, const VkAndroidSurfaceCreateInfoKHR*) {} 192 SurfaceKHR (VkInstance, const VkWin32SurfaceCreateInfoKHR*) {} 193 SurfaceKHR (VkInstance, const VkDisplaySurfaceCreateInfoKHR*) {} 194 ~SurfaceKHR (void) {} 195 }; 196 197 class DisplayModeKHR 198 { 199 public: 200 DisplayModeKHR (VkDisplayKHR, const VkDisplayModeCreateInfoKHR*) {} 201 ~DisplayModeKHR (void) {} 202 }; 203 204 class DebugReportCallbackEXT 205 { 206 public: 207 DebugReportCallbackEXT (VkInstance, const VkDebugReportCallbackCreateInfoEXT*) {} 208 ~DebugReportCallbackEXT (void) {} 209 }; 210 211 class Device 212 { 213 public: 214 Device (VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* deviceInfo); 215 ~Device (void) {} 216 217 PFN_vkVoidFunction getProcAddr (const char* name) const { return (PFN_vkVoidFunction)m_functions.getFunction(name); } 218 219 private: 220 const tcu::StaticFunctionLibrary m_functions; 221 }; 222 223 class Pipeline 224 { 225 public: 226 Pipeline (VkDevice, const VkGraphicsPipelineCreateInfo*) {} 227 Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {} 228 }; 229 230 class SwapchainKHR 231 { 232 public: 233 SwapchainKHR (VkDevice, const VkSwapchainCreateInfoKHR*) {} 234 ~SwapchainKHR (void) {} 235 }; 236 237 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo) 238 { 239 // \todo [2015-12-03 pyry] Alignment requirements? 240 // \todo [2015-12-03 pyry] Empty allocations okay? 241 if (pAllocInfo->allocationSize > 0) 242 { 243 void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize); 244 if (!heapPtr) 245 throw std::bad_alloc(); 246 return heapPtr; 247 } 248 else 249 return DE_NULL; 250 } 251 252 void freeHeap (void* ptr) 253 { 254 deFree(ptr); 255 } 256 257 class DeviceMemory 258 { 259 public: 260 DeviceMemory (VkDevice, const VkMemoryAllocateInfo* pAllocInfo) 261 : m_memory(allocateHeap(pAllocInfo)) 262 { 263 } 264 ~DeviceMemory (void) 265 { 266 freeHeap(m_memory); 267 } 268 269 void* getPtr (void) const { return m_memory; } 270 271 private: 272 void* const m_memory; 273 }; 274 275 class Buffer 276 { 277 public: 278 Buffer (VkDevice, const VkBufferCreateInfo* pCreateInfo) 279 : m_size(pCreateInfo->size) 280 {} 281 282 VkDeviceSize getSize (void) const { return m_size; } 283 284 private: 285 const VkDeviceSize m_size; 286 }; 287 288 class Image 289 { 290 public: 291 Image (VkDevice, const VkImageCreateInfo* pCreateInfo) 292 : m_imageType (pCreateInfo->imageType) 293 , m_format (pCreateInfo->format) 294 , m_extent (pCreateInfo->extent) 295 , m_samples (pCreateInfo->samples) 296 {} 297 298 VkImageType getImageType (void) const { return m_imageType; } 299 VkFormat getFormat (void) const { return m_format; } 300 VkExtent3D getExtent (void) const { return m_extent; } 301 VkSampleCountFlagBits getSamples (void) const { return m_samples; } 302 303 private: 304 const VkImageType m_imageType; 305 const VkFormat m_format; 306 const VkExtent3D m_extent; 307 const VkSampleCountFlagBits m_samples; 308 }; 309 310 class CommandBuffer 311 { 312 public: 313 CommandBuffer(VkDevice, VkCommandPool, VkCommandBufferLevel) 314 {} 315 }; 316 317 class DescriptorSet 318 { 319 public: 320 DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {} 321 }; 322 323 class DescriptorPool 324 { 325 public: 326 DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo) 327 : m_device (device) 328 , m_flags (pCreateInfo->flags) 329 {} 330 ~DescriptorPool (void) 331 { 332 reset(); 333 } 334 335 VkDescriptorSet allocate (VkDescriptorSetLayout setLayout); 336 void free (VkDescriptorSet set); 337 338 void reset (void); 339 340 private: 341 const VkDevice m_device; 342 const VkDescriptorPoolCreateFlags m_flags; 343 344 vector<DescriptorSet*> m_managedSets; 345 }; 346 347 VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout) 348 { 349 DescriptorSet* const impl = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout); 350 351 try 352 { 353 m_managedSets.push_back(impl); 354 } 355 catch (...) 356 { 357 delete impl; 358 throw; 359 } 360 361 return VkDescriptorSet(reinterpret_cast<deUintptr>(impl)); 362 } 363 364 void DescriptorPool::free (VkDescriptorSet set) 365 { 366 DescriptorSet* const impl = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal()); 367 368 DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT); 369 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 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 397 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getInstanceProcAddr (VkInstance instance, const char* pName) 398 { 399 return reinterpret_cast<Instance*>(instance)->getProcAddr(pName); 400 } 401 402 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL getDeviceProcAddr (VkDevice device, const char* pName) 403 { 404 return reinterpret_cast<Device*>(device)->getProcAddr(pName); 405 } 406 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 681 Instance::Instance (const VkInstanceCreateInfo*) 682 : m_functions(s_instanceFunctions, DE_LENGTH_OF_ARRAY(s_instanceFunctions)) 683 { 684 } 685 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: 694 NullDriverLibrary (void) 695 : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions)) 696 , m_driver (m_library) 697 {} 698 699 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 708 Library* createNullDriver (void) 709 { 710 return new NullDriverLibrary(); 711 } 712 713 } // vk 714