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