void getSemaphoreNative (const vk::DeviceInterface&						vkd,
						 vk::VkDevice									device,
						 vk::VkSemaphore								semaphore,
						 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR	externalType,
						 NativeHandle&									nativeHandle)
{
	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
	{
		const vk::VkSemaphoreGetFdInfoKHR	info	=
		{
			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
			DE_NULL,

			semaphore,
			externalType
		};
		int										fd	= -1;

		VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
		TCU_CHECK(fd >= 0);
		nativeHandle = fd;
	}
	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
	{
		const vk::VkSemaphoreGetWin32HandleInfoKHR	info	=
		{
			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
			DE_NULL,

			semaphore,
			externalType
		};
		vk::pt::Win32Handle							handle	(DE_NULL);

		VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));

		switch (externalType)
		{
			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
				break;

			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
				break;

			default:
				DE_FATAL("Unknow external memory handle type");
		}
	}
	else
		DE_FATAL("Unknow external semaphore handle type");
}
NativeHandle::NativeHandle (const NativeHandle& other)
	: m_fd				(-1)
	, m_win32HandleType	(WIN32HANDLETYPE_LAST)
	, m_win32Handle		(DE_NULL)
{
	if (other.m_fd >= 0)
	{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
		DE_ASSERT(!other.m_win32Handle.internal);
		m_fd = dup(other.m_fd);
		TCU_CHECK(m_fd >= 0);
#else
		DE_FATAL("Platform doesn't support file descriptors");
#endif
	}
	else if (other.m_win32Handle.internal)
	{
#if (DE_OS == DE_OS_WIN32)
		m_win32HandleType = other.m_win32HandleType;

		switch (other.m_win32HandleType)
		{
			case WIN32HANDLETYPE_NT:
			{
				DE_ASSERT(other.m_fd == -1);

				const HANDLE process = ::GetCurrentProcess();
				::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);

				break;
			}

			case WIN32HANDLETYPE_KMT:
			{
				m_win32Handle = other.m_win32Handle;
				break;
			}

			default:
				DE_FATAL("Unknown win32 handle type");
		}
#else
		DE_FATAL("Platform doesn't support win32 handles");
#endif
	}
	else
		DE_FATAL("Native handle can't be duplicated");
}
tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_BUFFER:
			return tcu::UVec3(imageSize.x(), 1u, 1u);

		case IMAGE_TYPE_1D_ARRAY:
			return tcu::UVec3(imageSize.x(), imageSize.z(), 1u);

		case IMAGE_TYPE_2D:
			return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);

		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_3D:
			return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());

		case IMAGE_TYPE_CUBE:
			return tcu::UVec3(imageSize.x(), imageSize.y(), 6u);

		case IMAGE_TYPE_CUBE_ARRAY:
			return tcu::UVec3(imageSize.x(), imageSize.y(), 6u * imageSize.z());

		default:
			DE_FATAL("Unknown image type");
			return tcu::UVec3(1u, 1u, 1u);
	}
}
deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_2D:
		case IMAGE_TYPE_3D:
		case IMAGE_TYPE_BUFFER:
			return 1u;

		case IMAGE_TYPE_1D_ARRAY:
		case IMAGE_TYPE_2D_ARRAY:
			return imageSize.z();

		case IMAGE_TYPE_CUBE:
			return 6u;

		case IMAGE_TYPE_CUBE_ARRAY:
			return imageSize.z() * 6u;

		default:
			DE_FATAL("Unknown image type");
			return 0u;
	}
}
ImageType getImageTypeForSingleLayer (const ImageType imageType)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_1D_ARRAY:
			return IMAGE_TYPE_1D;

		case IMAGE_TYPE_2D:
		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_CUBE:
		case IMAGE_TYPE_CUBE_ARRAY:
			// A single layer for cube is a 2d face
			return IMAGE_TYPE_2D;

		case IMAGE_TYPE_3D:
			return IMAGE_TYPE_3D;

		case IMAGE_TYPE_BUFFER:
			return IMAGE_TYPE_BUFFER;

		default:
			DE_FATAL("Internal test error");
			return IMAGE_TYPE_LAST;
	}
}
const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBitsKHR type)
{
	switch (type)
	{
		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
			return "opaque_fd";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
			return "opaque_win32";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
			return "opaque_win32_kmt";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR:
			return "d3d11_texture";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR:
			return "d3d11_texture_kmt";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR:
			return "d3d12_heap";

		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR:
			return "d3d12_resource";

		default:
			DE_FATAL("Unknown external memory type");
			return DE_NULL;
	}
}
static inline const char* getWindingShaderName (const Winding winding)
{
	switch (winding)
	{
		case WINDING_CCW:	return "ccw";
		case WINDING_CW:	return "cw";
		default:
			DE_FATAL("Unexpected winding type.");
			return DE_NULL;
	}
}
static inline const char* getShaderLanguageName (const ShaderLanguage language)
{
	switch (language)
	{
		case SHADER_LANGUAGE_GLSL:	return "glsl";
		case SHADER_LANGUAGE_HLSL:	return "hlsl";
		default:
			DE_FATAL("Unexpected shader language.");
			return DE_NULL;
	}
}
static inline const char* getOutputTopologyName (const TessPrimitiveType type, const Winding winding, const bool usePointMode)
{
	if (usePointMode)
		return "point";
	else if (type == TESSPRIMITIVETYPE_TRIANGLES || type == TESSPRIMITIVETYPE_QUADS)
		return (winding == WINDING_CCW ? "triangle_ccw" : "triangle_cw");
	else if (type == TESSPRIMITIVETYPE_ISOLINES)
		return "line";

	DE_FATAL("Unexpected primitive type.");
	return DE_NULL;
}
static inline const char* getPartitioningShaderName (SpacingMode mode)
{
	switch (mode)
	{
		case SPACINGMODE_EQUAL:				return "integer";
		case SPACINGMODE_FRACTIONAL_ODD:	return "fractional_odd";
		case SPACINGMODE_FRACTIONAL_EVEN:	return "fractional_even";
		default:
			DE_FATAL("Unexpected spacing mode.");
			return DE_NULL;
	}
}
static inline const char* getDomainName (const TessPrimitiveType type)
{
	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return "tri";
		case TESSPRIMITIVETYPE_QUADS:		return "quad";
		case TESSPRIMITIVETYPE_ISOLINES:	return "isoline";
		default:
			DE_FATAL("Unexpected primitive type.");
			return DE_NULL;
	}
}
void NativeHandle::reset (void)
{
	if (m_fd >= 0)
	{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
		DE_ASSERT(!m_win32Handle.internal);
		::close(m_fd);
#else
		DE_FATAL("Platform doesn't support file descriptors");
#endif
	}

	if (m_win32Handle.internal)
	{
#if (DE_OS == DE_OS_WIN32)
		switch (m_win32HandleType)
		{
			case WIN32HANDLETYPE_NT:
				DE_ASSERT(m_fd == -1);
				::CloseHandle((HANDLE)m_win32Handle.internal);
				break;

			case WIN32HANDLETYPE_KMT:
				break;

			default:
				DE_FATAL("Unknown win32 handle type");
		}
#else
		DE_FATAL("Platform doesn't support win32 handles");
#endif
	}

	m_fd				= -1;
	m_win32Handle		= vk::pt::Win32Handle(DE_NULL);
	m_win32HandleType	= WIN32HANDLETYPE_LAST;
}
void importSemaphore (const vk::DeviceInterface&					vkd,
					  const vk::VkDevice							device,
					  const vk::VkSemaphore							semaphore,
					  vk::VkExternalSemaphoreHandleTypeFlagBitsKHR	externalType,
					  NativeHandle&									handle,
					  vk::VkSemaphoreImportFlagsKHR					flags)
{
	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR
		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
	{
		const vk::VkImportSemaphoreFdInfoKHR	importInfo	=
		{
			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
			DE_NULL,
			semaphore,
			flags,
			externalType,
			handle.getFd()
		};

		VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
		handle.disown();
	}
	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
	{
		const vk::VkImportSemaphoreWin32HandleInfoKHR	importInfo	=
		{
			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
			DE_NULL,
			semaphore,
			flags,
			externalType,
			handle.getWin32Handle(),
			DE_NULL
		};

		VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
		// \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
		handle.reset();
	}
	else
		DE_FATAL("Unknown semaphore external handle type");
}
Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBitsKHR type)
{
	switch (type)
	{
		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
			return TRANSFERENCE_REFERENCE;

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
			return TRANSFERENCE_REFERENCE;

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
			return TRANSFERENCE_COPY;

		default:
			DE_FATAL("Unknown external fence type");
			return TRANSFERENCE_REFERENCE;
	}
}
static inline const char* getGeometryShaderOutputPrimitiveTypeShaderName (const TessPrimitiveType type, const bool usePointMode)
{
	if (usePointMode)
		return "points";

	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		case TESSPRIMITIVETYPE_QUADS:
			return "triangle_strip";

		case TESSPRIMITIVETYPE_ISOLINES:
			return "line_strip";

		default:
			DE_FATAL("Unexpected primitive type.");
			return DE_NULL;
	}
}
bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBitsKHR	type,
							Permanence									permanence)
{
	switch (type)
	{
		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
			return permanence == PERMANENCE_TEMPORARY;

		default:
			DE_FATAL("Unknown external fence type");
			return false;
	}
}
const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBitsKHR type)
{
	switch (type)
	{
		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
			return "opaque_fd";

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
			return "opaque_win32";

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
			return "opaque_win32_kmt";

		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
			return "sync_fd";

		default:
			DE_FATAL("Unknown external fence type");
			return DE_NULL;
	}
}
deUint32 getLayerDimensions (const ImageType imageType)
{
	switch (imageType)
	{
		case IMAGE_TYPE_1D:
		case IMAGE_TYPE_BUFFER:
		case IMAGE_TYPE_1D_ARRAY:
			return 1u;

		case IMAGE_TYPE_2D:
		case IMAGE_TYPE_2D_ARRAY:
		case IMAGE_TYPE_CUBE:
		case IMAGE_TYPE_CUBE_ARRAY:
			return 2u;

		case IMAGE_TYPE_3D:
			return 3u;

		default:
			DE_FATAL("Unknown image type");
			return 0u;
	}
}
Exemple #19
0
VkResult createSurface (const InstanceInterface&		vki,
						VkInstance						instance,
						Type							wsiType,
						const Display&					nativeDisplay,
						const Window&					nativeWindow,
						const VkAllocationCallbacks*	pAllocator,
						VkSurfaceKHR*					pSurface)
{
	// Update this function if you add more WSI implementations
	DE_STATIC_ASSERT(TYPE_LAST == 7);

	switch (wsiType)
	{
		case TYPE_XLIB:
		{
			const XlibDisplayInterface&			xlibDisplay		= dynamic_cast<const XlibDisplayInterface&>(nativeDisplay);
			const XlibWindowInterface&			xlibWindow		= dynamic_cast<const XlibWindowInterface&>(nativeWindow);
			const VkXlibSurfaceCreateInfoKHR	createInfo		=
			{
				VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkXlibSurfaceCreateFlagsKHR)0,
				xlibDisplay.getNative(),
				xlibWindow.getNative()
			};

			return vki.createXlibSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_XCB:
		{
			const XcbDisplayInterface&			xcbDisplay		= dynamic_cast<const XcbDisplayInterface&>(nativeDisplay);
			const XcbWindowInterface&			xcbWindow		= dynamic_cast<const XcbWindowInterface&>(nativeWindow);
			const VkXcbSurfaceCreateInfoKHR		createInfo		=
			{
				VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkXcbSurfaceCreateFlagsKHR)0,
				xcbDisplay.getNative(),
				xcbWindow.getNative()
			};

			return vki.createXcbSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_WAYLAND:
		{
			const WaylandDisplayInterface&		waylandDisplay	= dynamic_cast<const WaylandDisplayInterface&>(nativeDisplay);
			const WaylandWindowInterface&		waylandWindow	= dynamic_cast<const WaylandWindowInterface&>(nativeWindow);
			const VkWaylandSurfaceCreateInfoKHR	createInfo		=
			{
				VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkWaylandSurfaceCreateFlagsKHR)0,
				waylandDisplay.getNative(),
				waylandWindow.getNative()
			};

			return vki.createWaylandSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_MIR:
		{
			const MirDisplayInterface&			mirDisplay		= dynamic_cast<const MirDisplayInterface&>(nativeDisplay);
			const MirWindowInterface&			mirWindow		= dynamic_cast<const MirWindowInterface&>(nativeWindow);
			const VkMirSurfaceCreateInfoKHR		createInfo		=
			{
				VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkXcbSurfaceCreateFlagsKHR)0,
				mirDisplay.getNative(),
				mirWindow.getNative()
			};

			return vki.createMirSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_ANDROID:
		{
			const AndroidWindowInterface&		androidWindow	= dynamic_cast<const AndroidWindowInterface&>(nativeWindow);
			const VkAndroidSurfaceCreateInfoKHR	createInfo		=
			{
				VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkAndroidSurfaceCreateFlagsKHR)0,
				androidWindow.getNative()
			};

			return vki.createAndroidSurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_WIN32:
		{
			const Win32DisplayInterface&		win32Display	= dynamic_cast<const Win32DisplayInterface&>(nativeDisplay);
			const Win32WindowInterface&			win32Window		= dynamic_cast<const Win32WindowInterface&>(nativeWindow);
			const VkWin32SurfaceCreateInfoKHR	createInfo		=
			{
				VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
				DE_NULL,
				(VkWin32SurfaceCreateFlagsKHR)0,
				win32Display.getNative(),
				win32Window.getNative()
			};

			return vki.createWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface);
		}

		case TYPE_MACOS:
		{
			const MacOSWindowInterface&			macOSWindow		= dynamic_cast<const MacOSWindowInterface&>(nativeWindow);
			const VkMacOSSurfaceCreateInfoMVK	createInfo		=
			{
				VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
				DE_NULL,
				(VkMacOSSurfaceCreateFlagsMVK)0,
				macOSWindow.getNative()
			};

			return vki.createMacOSSurfaceMVK(instance, &createInfo, pAllocator, pSurface);
		}

		default:
			DE_FATAL("Unknown WSI type");
			return VK_ERROR_SURFACE_LOST_KHR;
	}
}
static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&				vkd,
												  vk::VkDevice								device,
												  vk::VkBuffer								buffer,
												  vk::VkImage								image,
												  const vk::VkMemoryRequirements&			requirements,
												  vk::VkExternalMemoryHandleTypeFlagBitsKHR	externalType,
												  NativeHandle&								handle)
{
	const bool	isDedicated		= !!buffer || !!image;

	DE_ASSERT(!buffer || !image);

	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
	{
		const vk::VkImportMemoryFdInfoKHR			importInfo		=
		{
			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
			DE_NULL,
			externalType,
			handle.getFd()
		};
		const vk::VkMemoryDedicatedAllocateInfoKHR	dedicatedInfo	=
		{
			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
			&importInfo,
			image,
			buffer,
		};
		const vk::VkMemoryAllocateInfo				info			=
		{
			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
			requirements.size,
			chooseMemoryType(requirements.memoryTypeBits)
		};
		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));

		handle.disown();

		return memory;
	}
	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
			|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
	{
		const vk::VkImportMemoryWin32HandleInfoKHR	importInfo =
		{
			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
			DE_NULL,
			externalType,
			handle.getWin32Handle(),
			DE_NULL
		};
		const vk::VkMemoryDedicatedAllocateInfoKHR	dedicatedInfo	=
		{
			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
			&importInfo,
			image,
			buffer,
		};
		const vk::VkMemoryAllocateInfo				info			=
		{
			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
			requirements.size,
			chooseMemoryType(requirements.memoryTypeBits)
		};
		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));

		handle.disown();

		return memory;
	}
	else
	{
		DE_FATAL("Unknown external memory type");
		return vk::Move<vk::VkDeviceMemory>();
	}
}