示例#1
0
void SwapChain::Initialize(void * WindowHandle, rhi::GfxSetting & gfxSetting)
{
	InitSurface(WindowHandle);
	VkPresentModeKHR swapchainPresentMode				= ChoosePresentMode();
	std::pair<VkFormat, VkColorSpaceKHR> chosenFormat	= ChooseFormat(gfxSetting);
	m_SelectedPresentQueueFamilyIndex					= ChooseQueueIndex();
	m_SwapchainExtent = { gfxSetting.Width, gfxSetting.Height };
	VkSurfaceCapabilitiesKHR surfProperties;
	K3D_VK_VERIFY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(GetPhysicalDevice(), m_Surface, &surfProperties));
	m_SwapchainExtent = surfProperties.currentExtent;
	/*gfxSetting.Width = m_SwapchainExtent.width;
	gfxSetting.Height = m_SwapchainExtent.height;*/
	uint32 desiredNumBuffers = kMath::Clamp(
		gfxSetting.BackBufferCount, 
		surfProperties.minImageCount, 
		surfProperties.maxImageCount);
	m_DesiredBackBufferCount = desiredNumBuffers;
	InitSwapChain(m_DesiredBackBufferCount, chosenFormat, swapchainPresentMode, surfProperties.currentTransform);
	K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, nullptr));
	m_ColorImages.resize(m_ReserveBackBufferCount);
	K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, m_ColorImages.data()));
	gfxSetting.BackBufferCount = m_ReserveBackBufferCount;
	VKLOG(Info, "[SwapChain::Initialize] desired imageCount=%d, reserved imageCount = %d.", m_DesiredBackBufferCount, m_ReserveBackBufferCount);
}
示例#2
0
	int XdevLSwapChainVulkan::create(VkCommandBuffer cmdBuffer, uint32_t *width, uint32_t *height) {

		VkResult result;

		VkSwapchainKHR oldSwapchain = m_swapChain;

		// Get physical device surface properties and formats.
		VkSurfaceCapabilitiesKHR surfCaps;
		result = fpGetPhysicalDeviceSurfaceCapabilitiesKHR(m_physicalDevice, m_surface, &surfCaps);
		if(VK_SUCCESS != result) {
			std::cerr << "vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}

		// -------------------------------------------------------------------------
		// Get available present modes.
		//

		// Get the number of modes.
		uint32_t presentModeCount;
		result = fpGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &presentModeCount, nullptr);
		if(VK_SUCCESS != result) {
			std::cerr << "vkGetPhysicalDeviceSurfacePresentModesKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}

		// Use the number of modes and create an array of modes.
		std::vector<VkPresentModeKHR> presentModes(presentModeCount);
		result = fpGetPhysicalDeviceSurfacePresentModesKHR(m_physicalDevice, m_surface, &presentModeCount, presentModes.data());
		if(VK_SUCCESS != result) {
			std::cerr << "vkGetPhysicalDeviceSurfacePresentModesKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}
		// -------------------------------------------------------------------------

		VkExtent2D swapchainExtent = {};
		// width and height are either both -1, or both not -1.
		if(surfCaps.currentExtent.width == UINT32_MAX) {
			// If the surface size is undefined, the size is set to
			// the size of the images requested.
			swapchainExtent.width = *width;
			swapchainExtent.height = *height;
		} else {
			// If the surface size is defined, the swap chain size must match
			swapchainExtent = surfCaps.currentExtent;
			*width = surfCaps.currentExtent.width;
			*height = surfCaps.currentExtent.height;
		}

		VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
		for(size_t i = 0; i < presentModeCount; i++) {
			if(presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
				swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
				break;
			}
			if((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
				swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
			}
		}

		// Determine the number of images
		uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
		if((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount)) {
			desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
		}

		VkSurfaceTransformFlagsKHR preTransform;
		if(surfCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
			preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
		} else {
			preTransform = surfCaps.currentTransform;
		}

		VkSwapchainCreateInfoKHR swapchainCI = {};
		swapchainCI.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
		swapchainCI.pNext = NULL;
		swapchainCI.surface = m_surface;
		swapchainCI.minImageCount = desiredNumberOfSwapchainImages;
		swapchainCI.imageFormat = m_colorFormat;
		swapchainCI.imageColorSpace = m_colorSpace;
		swapchainCI.imageExtent = { swapchainExtent.width, swapchainExtent.height };
		swapchainCI.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
		swapchainCI.preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform;
		swapchainCI.imageArrayLayers = 1;
		swapchainCI.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
		swapchainCI.queueFamilyIndexCount = 0;
		swapchainCI.pQueueFamilyIndices = NULL;
		swapchainCI.presentMode = swapchainPresentMode;
		swapchainCI.oldSwapchain = oldSwapchain;
		swapchainCI.clipped = true;
		swapchainCI.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

		// If we recreate a SwapChain we have to destroy the previous one.
		// Note: destroying the swapchain also cleans up all its associated
    // presentable images once the platform is done with them.
		if(m_oldSwapChain != VK_NULL_HANDLE) {
			fpDestroySwapchainKHR(m_device, m_oldSwapChain, nullptr);
		}

		result = fpCreateSwapchainKHR(m_device, &swapchainCI, nullptr, &m_swapChain);
		if(VK_SUCCESS != result) {
			std::cerr << "vkCreateSwapchainKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}

		result = fpGetSwapchainImagesKHR(m_device, m_swapChain, &m_imageCount, nullptr);
		if(VK_SUCCESS != result) {
			std::cerr << "vkGetSwapchainImagesKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}

		m_images.reserve(m_imageCount);
		m_images.resize(m_imageCount);

		result = fpGetSwapchainImagesKHR(m_device, m_swapChain, &m_imageCount, m_images.data());
		if(VK_SUCCESS != result) {
			std::cerr << "vkGetSwapchainImagesKHR failed: " << vkVkResultToString(result) << std::endl;
			return 1;
		}

		m_buffers.reserve(m_imageCount);
		m_buffers.resize(m_imageCount);

		for(uint32_t i = 0; i < m_imageCount; i++) {
			VkImageViewCreateInfo colorAttachmentView = {};
			colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
			colorAttachmentView.pNext = NULL;
			colorAttachmentView.format = m_colorFormat;
			colorAttachmentView.components = {
				VK_COMPONENT_SWIZZLE_R,
				VK_COMPONENT_SWIZZLE_G,
				VK_COMPONENT_SWIZZLE_B,
				VK_COMPONENT_SWIZZLE_A
			};
			colorAttachmentView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
			colorAttachmentView.subresourceRange.baseMipLevel = 0;
			colorAttachmentView.subresourceRange.levelCount = 1;
			colorAttachmentView.subresourceRange.baseArrayLayer = 0;
			colorAttachmentView.subresourceRange.layerCount = 1;
			colorAttachmentView.viewType = VK_IMAGE_VIEW_TYPE_2D;
			colorAttachmentView.flags = 0;

			m_buffers[i].image = m_images[i];

			// Transform images from initial (undefined) to present layout
			setImageLayout(
			  cmdBuffer,
			  m_buffers[i].image,
			  VK_IMAGE_ASPECT_COLOR_BIT,
			  VK_IMAGE_LAYOUT_UNDEFINED,
			  VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);

			colorAttachmentView.image = m_buffers[i].image;

			result = vkCreateImageView(m_device, &colorAttachmentView, nullptr, &m_buffers[i].view);
			assert(!result);
		}
		return 0;
	}