/*-------------------------------------------------------------------------
 * Vulkan CTS Framework
 * --------------------
 *
 * Copyright (c) 2016 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Windowing System Integration (WSI) Utilities.
 *//*--------------------------------------------------------------------*/

#include "vkWsiUtil.hpp"
#include "deArrayUtil.hpp"
#include "deMemory.h"

#include <limits>

namespace vk
{
namespace wsi
{

//! Get canonical WSI name that should be used for example in test case and group names.
const char* getName (Type wsiType)
{
	static const char* const s_names[] =
	{
		"xlib",
		"xcb",
		"wayland",
		"mir",
		"android",
		"win32",
		"macos",
	};
	return de::getSizedArrayElement<TYPE_LAST>(s_names, wsiType);
}

const char* getExtensionName (Type wsiType)
{
	static const char* const s_extNames[] =
	{
		"VK_KHR_xlib_surface",
		"VK_KHR_xcb_surface",
		"VK_KHR_wayland_surface",
		"VK_KHR_mir_surface",
		"VK_KHR_android_surface",
		"VK_KHR_win32_surface",
		"VK_MVK_macos_surface"
	};
	return de::getSizedArrayElement<TYPE_LAST>(s_extNames, wsiType);
}

const PlatformProperties& getPlatformProperties (Type wsiType)
{
	// \note These are declared here (rather than queried through vk::Platform for example)
	//		 on purpose. The behavior of a platform is partly defined by the platform spec,
	//		 and partly by WSI extensions, and platform ports should not need to override
	//		 that definition.

	const deUint32	noDisplayLimit	= std::numeric_limits<deUint32>::max();
	const deUint32	noWindowLimit	= std::numeric_limits<deUint32>::max();

	static const PlatformProperties s_properties[] =
	{
		// VK_KHR_xlib_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
			PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
		// VK_KHR_xcb_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
			PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
		// VK_KHR_wayland_surface
		{
			0u,
			PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
		// VK_KHR_mir_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
			PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
		// VK_KHR_android_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE,
			PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE,
			1u,
			1u, // Only one window available
		},
		// VK_KHR_win32_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
			PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
		// VK_MVK_macos_surface
		{
			PlatformProperties::FEATURE_INITIAL_WINDOW_SIZE|PlatformProperties::FEATURE_RESIZE_WINDOW,
			PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE,
			noDisplayLimit,
			noWindowLimit,
		},
	};

	return de::getSizedArrayElement<TYPE_LAST>(s_properties, wsiType);
}

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;
	}
}

Move<VkSurfaceKHR> createSurface (const InstanceInterface&		vki,
								  VkInstance					instance,
								  Type							wsiType,
								  const Display&				nativeDisplay,
								  const Window&					nativeWindow,
								  const VkAllocationCallbacks*	pAllocator)
{
	VkSurfaceKHR object = 0;
	VK_CHECK(createSurface(vki, instance, wsiType, nativeDisplay, nativeWindow, pAllocator, &object));
	return Move<VkSurfaceKHR>(check<VkSurfaceKHR>(object), Deleter<VkSurfaceKHR>(vki, instance, pAllocator));
}

VkBool32 getPhysicalDeviceSurfaceSupport (const InstanceInterface&	vki,
										  VkPhysicalDevice			physicalDevice,
										  deUint32					queueFamilyIndex,
										  VkSurfaceKHR				surface)
{
	VkBool32 result = 0;

	VK_CHECK(vki.getPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, &result));

	return result;
}

VkSurfaceCapabilitiesKHR getPhysicalDeviceSurfaceCapabilities (const InstanceInterface&		vki,
															   VkPhysicalDevice				physicalDevice,
															   VkSurfaceKHR					surface)
{
	VkSurfaceCapabilitiesKHR capabilities;

	deMemset(&capabilities, 0, sizeof(capabilities));

	VK_CHECK(vki.getPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities));

	return capabilities;
}

std::vector<VkSurfaceFormatKHR> getPhysicalDeviceSurfaceFormats (const InstanceInterface&		vki,
																 VkPhysicalDevice				physicalDevice,
																 VkSurfaceKHR					surface)
{
	deUint32	numFormats	= 0;

	VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, DE_NULL));

	if (numFormats > 0)
	{
		std::vector<VkSurfaceFormatKHR>	formats	(numFormats);

		VK_CHECK(vki.getPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &numFormats, &formats[0]));

		return formats;
	}
	else
		return std::vector<VkSurfaceFormatKHR>();
}

std::vector<VkPresentModeKHR> getPhysicalDeviceSurfacePresentModes (const InstanceInterface&		vki,
																	VkPhysicalDevice				physicalDevice,
																	VkSurfaceKHR					surface)
{
	deUint32	numModes	= 0;

	VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, DE_NULL));

	if (numModes > 0)
	{
		std::vector<VkPresentModeKHR>	modes	(numModes);

		VK_CHECK(vki.getPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &numModes, &modes[0]));

		return modes;
	}
	else
		return std::vector<VkPresentModeKHR>();
}

std::vector<VkImage> getSwapchainImages (const DeviceInterface&			vkd,
										 VkDevice						device,
										 VkSwapchainKHR					swapchain)
{
	deUint32	numImages	= 0;

	VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, DE_NULL));

	if (numImages > 0)
	{
		std::vector<VkImage>	images	(numImages);

		VK_CHECK(vkd.getSwapchainImagesKHR(device, swapchain, &numImages, &images[0]));

		return images;
	}
	else
		return std::vector<VkImage>();
}

} // wsi
} // vk
