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