Home | History | Annotate | Download | only in vulkan
      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