create device & swapchain
This commit is contained in:
		
							parent
							
								
									d8163fd614
								
							
						
					
					
						commit
						e48d175b76
					
				| @ -8,6 +8,7 @@ namespace vulkanapi { | ||||
| 		mInstance = new Instance(instanceCreator); | ||||
| 		 | ||||
| 		auto deviceCreator = DeviceCreator(*mInstance); | ||||
| 		deviceCreator.AddWindowExtension(); | ||||
| 		deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE; | ||||
| 		deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); | ||||
| 		deviceCreator.AddQueue("RenderQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); | ||||
| @ -15,6 +16,7 @@ namespace vulkanapi { | ||||
| 		deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); | ||||
| 		mDevice = new Device(deviceCreator); | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 	Backend::~Backend() | ||||
| 	{ | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| #include "wrapper/instance.h" | ||||
| #include "wrapper/device.h" | ||||
| #include "wrapper/swapchain.h" | ||||
| #include "wrapper/swapchain_creator.h" | ||||
| #include <vulkan/vulkan_win32.h> | ||||
| namespace vulkanapi { | ||||
| 	Window::Window(Backend& backend, int frames, uint32_t width, uint32_t height, const char* title) | ||||
| @ -19,7 +20,7 @@ namespace vulkanapi { | ||||
| 		  mPtr											    // HWND                            hwnd
 | ||||
| 		}; | ||||
| 		vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &mSurfaceKHR); | ||||
| 
 | ||||
| 		mSwapchain = new Swapchain(backend.GetDevice(), frames, width, height, mSurfaceKHR); | ||||
| 		SwapchainCreator swapchainCreator(backend.GetDevice(), frames, width, height, mSurfaceKHR); | ||||
| 		mSwapchain = new Swapchain(swapchainCreator); | ||||
| 	} | ||||
| } | ||||
| @ -1,21 +1,38 @@ | ||||
| #include "device.h" | ||||
| #include "device_creator.h" | ||||
| #include "zlog.h" | ||||
| namespace vulkanapi { | ||||
|     Device::Device(DeviceCreator& Creator) | ||||
|     { | ||||
| 
 | ||||
|     }     | ||||
|     uint32_t Device::GetQueueFamilyIndex(VkQueueFlags flag) | ||||
|     { | ||||
|         Creator.FindDevice(mPhysical); | ||||
|         std::vector<VkQueueFamilyProperties> queue_families; | ||||
|        // CheckAvailableQueueFamiliesAndTheirProperties(mPhysical, queue_families);
 | ||||
|         for (uint32_t i = 0, l = queue_families.size(); i < l; i++) { | ||||
|             if ((queue_families[i].queueFlags & flag) == flag) { | ||||
|                 return i; | ||||
|             } | ||||
|         Creator.CheckAvailableQueueFamilies(mPhysical, queue_families); | ||||
|         std::vector<VkDeviceQueueCreateInfo> queue_create_infos; | ||||
|         std::vector<std::vector<float>> queue_prioritie; | ||||
|         Creator.QueueCreateInfos(queue_create_infos, queue_prioritie, queue_families); | ||||
|         auto extensions = Creator.EnabledExtensionNames(); | ||||
|         VkDeviceCreateInfo device_create_info = { | ||||
|           VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,               // VkStructureType                  sType
 | ||||
|           nullptr,                                            // const void                     * pNext
 | ||||
|           0,                                                  // VkDeviceCreateFlags              flags
 | ||||
|           static_cast<uint32_t>(queue_create_infos.size()),   // uint32_t                         queueCreateInfoCount
 | ||||
|           queue_create_infos.data(),                          // const VkDeviceQueueCreateInfo  * pQueueCreateInfos
 | ||||
|           0,                                                  // uint32_t                         enabledLayerCount
 | ||||
|           nullptr,                                            // const char * const             * ppEnabledLayerNames
 | ||||
|           static_cast<uint32_t>(extensions.size()),           // uint32_t                         enabledExtensionCount
 | ||||
|           extensions.data(),                                  // const char * const             * ppEnabledExtensionNames
 | ||||
|           &Creator.desiredPhysicalDeviceFeatures              // const VkPhysicalDeviceFeatures * pEnabledFeatures
 | ||||
|         }; | ||||
| #ifdef _USE_GRAPHIC_DEBUG | ||||
|         auto layers = Creator.EnabledLayerNames(); | ||||
|         device_create_info.enabledLayerCount = layers.size(); | ||||
|         device_create_info.ppEnabledLayerNames = layers.data(); | ||||
| #endif // _USE_GRAPHIC_DEBUG
 | ||||
|         VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr); | ||||
|         if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) { | ||||
|             zlog::error("Could not create logical device."); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|     }     | ||||
|     VkCommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) | ||||
|     { | ||||
|         VkCommandPool pCommandPool; | ||||
|  | ||||
| @ -18,8 +18,6 @@ namespace vulkanapi { | ||||
| 		} | ||||
| 	public: | ||||
| 		Device(DeviceCreator& Creator); | ||||
| 
 | ||||
| 		uint32_t GetQueueFamilyIndex(VkQueueFlags flag); | ||||
| 		VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); | ||||
| 		VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex); | ||||
| 		VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| #pragma once | ||||
| #include "device.h" | ||||
| #include "device_creator.h" | ||||
| #include "instance.h" | ||||
| #include "zlog.h" | ||||
| namespace vulkanapi { | ||||
| 	DeviceCreator::DeviceCreator(Instance& instance) | ||||
| @ -23,10 +24,100 @@ namespace vulkanapi { | ||||
| 		AddLayer("VK_LAYER_RENDERDOC_Capture"); | ||||
| #endif | ||||
| 	} | ||||
| 	void DeviceCreator::QueueCreateInfos(std::vector<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<VkQueueFamilyProperties>& queue_families) | ||||
| 	bool DeviceCreator::CheckProperty(const VkPhysicalDevice device) | ||||
| 	{ | ||||
| 		std::vector<VkLayerProperties> availableLayers(); | ||||
| 		 | ||||
| 		VkPhysicalDeviceProperties deviceProperties; | ||||
| 		vkGetPhysicalDeviceProperties(device, &deviceProperties); | ||||
| 		return (deviceProperties.deviceType & desiredPhysicalDeviceType) == desiredPhysicalDeviceType; | ||||
| 	} | ||||
| 	bool DeviceCreator::CheckExtension(const VkPhysicalDevice device) | ||||
| 	{ | ||||
| 		uint32_t extensionCount = 0; | ||||
| 		vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); | ||||
| 		std::vector<VkExtensionProperties> availableExtensions(extensionCount); | ||||
| 		vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); | ||||
| 		for (const auto& desiredExtension : desiredExtensions) | ||||
| 		{ | ||||
| 			bool find = false; | ||||
| 			for (const auto& availableExtension : availableExtensions) | ||||
| 			{ | ||||
| 				if (strcmp(availableExtension.extensionName, desiredExtension.c_str()) == 0) | ||||
| 				{ | ||||
| 					find = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (!find)return false; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 	bool DeviceCreator::FindDevice(VkPhysicalDevice& device) | ||||
| 	{ | ||||
| 		std::vector<VkPhysicalDevice> available_devices; | ||||
| 		instance.EnumerateAvailablePhysicalDevices(available_devices); | ||||
| 		for (int i = 0, size = available_devices.size(); i < size;i++) | ||||
| 		{ | ||||
| 			device = available_devices[i]; | ||||
| 			if (!CheckProperty(device))continue; | ||||
| 			if (!CheckExtension(device))continue; | ||||
| #ifdef _USE_GRAPHIC_DEBUG | ||||
| 			if (!CheckLayer(device))continue; | ||||
| #endif // _USE_GRAPHIC_DEBUG
 | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 	std::vector<char const*> DeviceCreator::EnabledExtensionNames() | ||||
| 	{ | ||||
| 		std::vector<char const*> _extension; | ||||
| 		for (int i = 0, l = desiredExtensions.size(); i < l; i++) { | ||||
| 			_extension.push_back(desiredExtensions[i].c_str()); | ||||
| 		} | ||||
| 		return _extension; | ||||
| 	} | ||||
| 	void DeviceCreator::QueueCreateInfos(std::vector<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<std::vector<float>>& queue_prioritie, | ||||
| 		std::vector<VkQueueFamilyProperties>& queue_families) | ||||
| 	{ | ||||
| 		uint32_t size = queue_families.size(); | ||||
| 		for (uint32_t i = 0; i < size; i++) { | ||||
| 			VkDeviceQueueCreateInfo queueCreateInfo{}; | ||||
| 			queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; | ||||
| 			queueCreateInfo.queueFamilyIndex = i; | ||||
| 			queueCreateInfo.queueCount = 0; | ||||
| 			queue_create_infos.push_back(queueCreateInfo); | ||||
| 			queue_prioritie.emplace_back(std::vector<float>{}); | ||||
| 		} | ||||
| 		uint32_t max_value = 1; | ||||
| 		for (const auto& queue : desiredQueues) { | ||||
| 			uint32_t index = -1; | ||||
| 			bool bFind = false; | ||||
| 			for (uint32_t i = 0; i < size; i++) { | ||||
| 				auto family = queue_families[i]; | ||||
| 				if ((family.queueFlags & queue.flag) == queue.flag) { | ||||
| 					index = i; | ||||
| 					if (queue_create_infos[i].queueCount < max_value * family.queueCount) { | ||||
| 						bFind = true; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if (index != -1 && queue_create_infos[index].queueCount < queue_families[index].queueCount) { | ||||
| 				queue_create_infos[index].queueCount++; | ||||
| 				queue_prioritie[index].push_back(queue.prioritie); | ||||
| 			} | ||||
| 			if (!bFind) | ||||
| 				max_value++; | ||||
| 		} | ||||
| 		auto it = queue_create_infos.begin(); | ||||
| 		for (uint32_t i = 0; i < size; i++) { | ||||
| 			if (it->queueCount == 0) { | ||||
| 				it = queue_create_infos.erase(it); | ||||
| 			} | ||||
| 			else { | ||||
| 				it->pQueuePriorities = queue_prioritie[i].data(); | ||||
| 				it++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	void DeviceCreator::AddExtension(std::string extensionName) | ||||
| 	{ | ||||
| @ -37,5 +128,50 @@ namespace vulkanapi { | ||||
| 	{ | ||||
| 		desiredLayers.push_back(layerName); | ||||
| 	} | ||||
| 	bool DeviceCreator::CheckLayer(const VkPhysicalDevice device) | ||||
| 	{ | ||||
| 		uint32_t layerCount = 0; | ||||
| 		vkEnumerateDeviceLayerProperties(device, &layerCount, nullptr); | ||||
| 		std::vector<VkLayerProperties> availableLayers(layerCount); | ||||
| 		vkEnumerateDeviceLayerProperties(device, &layerCount, availableLayers.data()); | ||||
| 		for (const auto& desiredLayer : desiredLayers) | ||||
| 		{ | ||||
| 			bool find = false; | ||||
| 			for (const auto& availableLayer : availableLayers) | ||||
| 			{ | ||||
| 				if (strcmp(availableLayer.layerName, desiredLayer.c_str()) == 0) | ||||
| 				{ | ||||
| 					find = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (!find)return false; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 	std::vector<char const*> DeviceCreator::EnabledLayerNames() | ||||
| 	{ | ||||
| 		std::vector<char const*> _extension; | ||||
| 		for (int i = 0, l = desiredLayers.size(); i < l; i++) { | ||||
| 			_extension.push_back(desiredLayers[i].c_str()); | ||||
| 		} | ||||
| 		return _extension; | ||||
| 	} | ||||
| #endif | ||||
| 	bool DeviceCreator::CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector<VkQueueFamilyProperties>& queue_families) { | ||||
| 		uint32_t queue_families_count = 0; | ||||
| 
 | ||||
| 		vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr); | ||||
| 		if (queue_families_count == 0) { | ||||
| 			zlog::error("Could not get the number of queue families."); | ||||
| 			return false; | ||||
| 		} | ||||
| 		queue_families.resize(queue_families_count); | ||||
| 		vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, queue_families.data()); | ||||
| 		if (queue_families_count == 0) { | ||||
| 			zlog::error("Could not acquire properties of queue families."); | ||||
| 			return false; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
| @ -16,7 +16,7 @@ namespace vulkanapi { | ||||
| 			VkQueueFlags flag; | ||||
| 			float prioritie; | ||||
| 			DesiredQueue(std::string name, VkQueueFlags flag, float prioritie) | ||||
| 				: name(name), flag(flag), prioritie(prioritie){} | ||||
| 				: name(name), flag(flag), prioritie(prioritie) {} | ||||
| 		}; | ||||
| 	public: | ||||
| 		VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures; | ||||
| @ -31,12 +31,21 @@ namespace vulkanapi { | ||||
| 		void AddQueue(std::string name, VkQueueFlags flag, float prioritie); | ||||
| 		void AddExtension(std::string extensionName); | ||||
| 		void AddWindowExtension(); | ||||
| 		void QueueCreateInfos(std::vector<VkDeviceQueueCreateInfo>& queue_create_infos, std::vector<VkQueueFamilyProperties>& queue_families); | ||||
| 		bool CheckProperty(const VkPhysicalDevice device); | ||||
| 		bool CheckExtension(const VkPhysicalDevice device); | ||||
| 		bool FindDevice(VkPhysicalDevice& device); | ||||
| 		std::vector<char const*> EnabledExtensionNames(); | ||||
| 		void QueueCreateInfos(std::vector<VkDeviceQueueCreateInfo>& queue_create_infos, | ||||
| 			std::vector<std::vector<float>>& queue_prioritie, | ||||
| 			std::vector<VkQueueFamilyProperties>& queue_families); | ||||
| #ifdef _USE_GRAPHIC_DEBUG | ||||
| 	public: | ||||
| 		std::vector<std::string> desiredLayers; | ||||
| 		void AddLayer(std::string layerName); | ||||
| 		bool CheckLayer(const VkPhysicalDevice device); | ||||
| 		std::vector<char const*> EnabledLayerNames(); | ||||
| #endif | ||||
| 	private: | ||||
| 		 | ||||
| 		static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, std::vector<VkQueueFamilyProperties>& queue_families); | ||||
| 	}; | ||||
| }; | ||||
| @ -1,43 +1,50 @@ | ||||
| #include "swapchain.h" | ||||
| #include "swapchain_help.h" | ||||
| #include "swapchain_creator.h" | ||||
| #include "device.h" | ||||
| #include "image.h" | ||||
| #include "zlog.h" | ||||
| namespace vulkanapi { | ||||
| 	Swapchain::Swapchain(Device& device, int frames, int width, int height, VkSurfaceKHR presentation_surface) | ||||
| 	Swapchain::Swapchain(SwapchainCreator& Creator) | ||||
| 		: mPtr(nullptr) | ||||
| 	{ | ||||
| 		uint32_t queue_family_index; | ||||
| 		VkPhysicalDevice physical_device = device.GetPhysical(); | ||||
| 
 | ||||
| 		//选择交换链图像的格式与颜色空间
 | ||||
| 		VkFormat image_format; | ||||
| 		VkColorSpaceKHR image_color_space; | ||||
| 		SelectFormatOfSwapchainImages(physical_device, presentation_surface, { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }, | ||||
| 			image_format, image_color_space); | ||||
| 
 | ||||
| 		VkSurfaceCapabilitiesKHR surface_capabilities; | ||||
| 		GetCapabilitiesOfPresentationSurface(physical_device, presentation_surface, surface_capabilities); | ||||
| 
 | ||||
| 		VkExtent2D image_size{ (uint32_t)width ,(uint32_t)height }; | ||||
| 		ChooseSizeOfSwapchainImages(surface_capabilities, image_size); | ||||
| 
 | ||||
| 		//调用设备接口,创建交换链
 | ||||
| 		VkSwapchainKHR old_swapchain = VK_NULL_HANDLE; | ||||
| 		VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; | ||||
| 		CreateSwapchain(device.Ptr(), presentation_surface, frames, { image_format, image_color_space }, image_size | ||||
| 			, imageUsage, VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,VK_PRESENT_MODE_FIFO_KHR, old_swapchain, mPtr); | ||||
| 
 | ||||
| 		VkSurfaceCapabilitiesKHR capabilities{}; | ||||
| 		vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Creator.device.GetPhysical(), Creator.presentation_surface, &capabilities); | ||||
| 		VkExtent2D image_extent = Creator.EnableImageExtent2D(capabilities); | ||||
| 		VkSwapchainCreateInfoKHR swapchain_create_info = { | ||||
| 			VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,// VkStructureType                  sType
 | ||||
| 			nullptr,                                    // const void                     * pNext
 | ||||
| 			0,                                          // VkSwapchainCreateFlagsKHR        flags
 | ||||
| 			Creator.presentation_surface,               // VkSurfaceKHR                     surface
 | ||||
| 			(uint32_t)Creator.frames,                             // uint32_t                         minImageCount
 | ||||
| 			Creator.imageFormat,                        // VkFormat                         imageFormat
 | ||||
| 			Creator.imageColorSpace,                    // VkColorSpaceKHR                  imageColorSpace
 | ||||
| 			image_extent,                                 // VkExtent2D                       imageExtent
 | ||||
| 			1,                                          // uint32_t                         imageArrayLayers
 | ||||
| 			Creator.imageUsage,                         // VkImageUsageFlags                imageUsage
 | ||||
| 			VK_SHARING_MODE_EXCLUSIVE,                  // VkSharingMode                    imageSharingMode
 | ||||
| 			0,                                          // uint32_t                         queueFamilyIndexCount
 | ||||
| 			nullptr,                                    // const uint32_t                 * pQueueFamilyIndices
 | ||||
| 			capabilities.currentTransform,              // VkSurfaceTransformFlagBitsKHR    preTransform
 | ||||
| 			VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,          // VkCompositeAlphaFlagBitsKHR      compositeAlpha
 | ||||
| 			Creator.presentMode,                        // VkPresentModeKHR                 presentMode
 | ||||
| 			VK_TRUE,                                    // VkBool32                         clipped
 | ||||
| 			VK_NULL_HANDLE                              // VkSwapchainKHR                   oldSwapchain
 | ||||
| 		}; | ||||
| 		VkResult result = vkCreateSwapchainKHR(Creator.device.Ptr(), &swapchain_create_info, nullptr, &mPtr); | ||||
| 		if (result != VK_SUCCESS) { | ||||
| 			zlog::error("Failed to create swap chain."); | ||||
| 		} | ||||
| 		std::vector<VkImage> swapchain_images; | ||||
| 		GetHandlesOfSwapchainImages(device.Ptr(), mPtr, swapchain_images); | ||||
| 		Creator.CreateSwapchainImages(mPtr, swapchain_images); | ||||
| 		uint32_t image_count = swapchain_images.size(); | ||||
| 		for (auto img : swapchain_images) { | ||||
| 			mImages.push_back(new Image(device, img, Image::Args{ | ||||
| 			mImages.push_back(new Image(Creator.device, img, Image::Args{ | ||||
| 				1, | ||||
| 					"", | ||||
| 					width, height, | ||||
| 					1, 1, 1, | ||||
| 					image_format, imageUsage, | ||||
| 					1, 1, 1, 1})); | ||||
| 				"", | ||||
| 				(int)Creator.width, (int)Creator.height, | ||||
| 				1, 1, 1, | ||||
| 				Creator.imageFormat, Creator.imageUsage, | ||||
| 				1, 1, 1, 1})); | ||||
| 		} | ||||
|  	} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -4,13 +4,14 @@ | ||||
| #include "../vulkan.h" | ||||
| 
 | ||||
| namespace vulkanapi { | ||||
| 	class Device; | ||||
| 	class Image; | ||||
| 	class SwapchainCreator; | ||||
| 	class Swapchain { | ||||
| 		friend class SwapchainCreator; | ||||
| 	protected: | ||||
| 		VkSwapchainKHR mPtr; | ||||
| 		std::vector<Image*> mImages; | ||||
| 	public: | ||||
| 		Swapchain(Device& device,int frames, int width, int height, VkSurfaceKHR presentation_surface); | ||||
| 		Swapchain(SwapchainCreator& Creator); | ||||
| 	}; | ||||
| }; | ||||
							
								
								
									
										43
									
								
								engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| #include "swapchain_creator.h" | ||||
| #include "device.h" | ||||
| #include <algorithm> | ||||
| namespace vulkanapi { | ||||
| 	SwapchainCreator::SwapchainCreator(Device& device, int frames, uint32_t width, uint32_t height, | ||||
| 		VkSurfaceKHR presentation_surface) | ||||
| 		: device(device) | ||||
| 		, presentation_surface(presentation_surface) | ||||
| 		, frames(frames) | ||||
| 		, width(width) | ||||
| 		, height(height) | ||||
| 		, imageFormat(VkFormat::VK_FORMAT_B8G8R8A8_SRGB) | ||||
| 		, imageColorSpace(VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) | ||||
| 		, presentMode(VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR) | ||||
| 		, imageUsage(VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_DST_BIT) | ||||
| 		, maxFrameInFlightCount(2) | ||||
| 	{ | ||||
| 
 | ||||
| 	} | ||||
| 	VkExtent2D SwapchainCreator::EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities) | ||||
| 	{ | ||||
| 		VkExtent2D image_extent{ width , height }; | ||||
| 		if (capabilities.currentExtent.width != 0xFFFFFFFF) | ||||
| 		{ | ||||
| 			image_extent = capabilities.currentExtent; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			image_extent.width = std::clamp(image_extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); | ||||
| 			image_extent.height = std::clamp(image_extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); | ||||
| 		} | ||||
| 		return image_extent; | ||||
| 	} | ||||
| 	bool SwapchainCreator::CreateSwapchainImages(VkSwapchainKHR swapchain, std::vector<VkImage>& swapchain_images) | ||||
| 	{ | ||||
| 		uint32_t imageCount = 0; | ||||
| 		vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, nullptr); | ||||
| 		std::vector<VkImage> scImages = std::vector<VkImage>(imageCount); | ||||
| 		swapchain_images.resize(imageCount); | ||||
| 		vkGetSwapchainImagesKHR(device.Ptr(), swapchain, &imageCount, swapchain_images.data()); | ||||
| 		return true; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										30
									
								
								engine/src/engine/vulkanapi/wrapper/swapchain_creator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								engine/src/engine/vulkanapi/wrapper/swapchain_creator.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| #pragma once | ||||
| #include "../vulkan.h" | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace vulkanapi { | ||||
| 	class Device; | ||||
| 	class SwapchainCreator { | ||||
| 		friend class Swapchain; | ||||
| 	public: | ||||
| 		int frames; | ||||
| 		uint32_t width; | ||||
| 		uint32_t height; | ||||
| 		std::string title; | ||||
| 		VkFormat imageFormat; | ||||
| 		VkColorSpaceKHR imageColorSpace; | ||||
| 		VkPresentModeKHR presentMode; | ||||
| 		VkImageUsageFlags imageUsage; | ||||
| 		uint32_t maxFrameInFlightCount; | ||||
| 
 | ||||
| 	public: | ||||
| 		VkSurfaceKHR presentation_surface; | ||||
| 		Device& device; | ||||
| 	public: | ||||
| 		SwapchainCreator(Device& device,int frames,uint32_t width, uint32_t height, VkSurfaceKHR presentation_surface); | ||||
| 		 | ||||
| 		VkExtent2D EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities); | ||||
| 		bool CreateSwapchainImages(VkSwapchainKHR swapchain,std::vector<VkImage>& swapchain_images); | ||||
| 	}; | ||||
| }; | ||||
| @ -1,162 +0,0 @@ | ||||
| #pragma once | ||||
| #include "instance.h" | ||||
| #include <iostream> | ||||
| #include "zlog.h" | ||||
| namespace vulkanapi { | ||||
|     bool GetCapabilitiesOfPresentationSurface(VkPhysicalDevice           physical_device, | ||||
|         VkSurfaceKHR               presentation_surface, | ||||
|         VkSurfaceCapabilitiesKHR& surface_capabilities) { | ||||
|         VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, presentation_surface, &surface_capabilities); | ||||
| 
 | ||||
|         if (VK_SUCCESS != result) { | ||||
|             zlog::error("Could not get the capabilities of a presentation surface."); | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     bool ChooseSizeOfSwapchainImages(VkSurfaceCapabilitiesKHR const& surface_capabilities, | ||||
|         VkExtent2D& size_of_images) { | ||||
|         if (0xFFFFFFFF == surface_capabilities.currentExtent.width) { | ||||
|             if (size_of_images.width < surface_capabilities.minImageExtent.width) { | ||||
|                 size_of_images.width = surface_capabilities.minImageExtent.width; | ||||
|             } | ||||
|             else if (size_of_images.width > surface_capabilities.maxImageExtent.width) { | ||||
|                 size_of_images.width = surface_capabilities.maxImageExtent.width; | ||||
|             } | ||||
| 
 | ||||
|             if (size_of_images.height < surface_capabilities.minImageExtent.height) { | ||||
|                 size_of_images.height = surface_capabilities.minImageExtent.height; | ||||
|             } | ||||
|             else if (size_of_images.height > surface_capabilities.maxImageExtent.height) { | ||||
|                 size_of_images.height = surface_capabilities.maxImageExtent.height; | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             size_of_images = surface_capabilities.currentExtent; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     bool SelectFormatOfSwapchainImages(VkPhysicalDevice     physical_device, | ||||
|         VkSurfaceKHR         presentation_surface, | ||||
|         VkSurfaceFormatKHR   desired_surface_format, | ||||
|         VkFormat& image_format, | ||||
|         VkColorSpaceKHR& image_color_space) { | ||||
|         // Enumerate supported formats
 | ||||
|         uint32_t formats_count = 0; | ||||
|         VkResult result = VK_SUCCESS; | ||||
| 
 | ||||
|         result = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, presentation_surface, &formats_count, nullptr); | ||||
|         if ((VK_SUCCESS != result) || | ||||
|             (0 == formats_count)) { | ||||
|             zlog::error("Could not get the number of supported surface formats."); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         std::vector<VkSurfaceFormatKHR> surface_formats(formats_count); | ||||
|         result = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, presentation_surface, &formats_count, surface_formats.data()); | ||||
|         if ((VK_SUCCESS != result) || | ||||
|             (0 == formats_count)) { | ||||
|             zlog::error("Could not enumerate supported surface formats."); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // Select surface format
 | ||||
|         if ((1 == surface_formats.size()) && | ||||
|             (VK_FORMAT_UNDEFINED == surface_formats[0].format)) { | ||||
|             image_format = desired_surface_format.format; | ||||
|             image_color_space = desired_surface_format.colorSpace; | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         for (auto& surface_format : surface_formats) { | ||||
|             if ((desired_surface_format.format == surface_format.format) && | ||||
|                 (desired_surface_format.colorSpace == surface_format.colorSpace)) { | ||||
|                 image_format = desired_surface_format.format; | ||||
|                 image_color_space = desired_surface_format.colorSpace; | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (auto& surface_format : surface_formats) { | ||||
|             if (desired_surface_format.format == surface_format.format) { | ||||
|                 image_format = desired_surface_format.format; | ||||
|                 image_color_space = surface_format.colorSpace; | ||||
|                 zlog::error("Desired combination of format and colorspace is not supported. Selecting other colorspace."); | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         image_format = surface_formats[0].format; | ||||
|         image_color_space = surface_formats[0].colorSpace; | ||||
|         zlog::error("Desired format is not supported. Selecting available format - colorspace combination."); | ||||
|         return true; | ||||
|     } | ||||
|     bool CreateSwapchain(VkDevice                        logical_device, | ||||
|         VkSurfaceKHR                    presentation_surface, | ||||
|         uint32_t                        image_count, | ||||
|         VkSurfaceFormatKHR              surface_format, | ||||
|         VkExtent2D                      image_size, | ||||
|         VkImageUsageFlags               image_usage, | ||||
|         VkSurfaceTransformFlagBitsKHR   surface_transform, | ||||
|         VkPresentModeKHR                present_mode, | ||||
|         VkSwapchainKHR& old_swapchain, | ||||
|         VkSwapchainKHR& swapchain) { | ||||
|         VkSwapchainCreateInfoKHR swapchain_create_info = { | ||||
|           VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,  // VkStructureType                  sType
 | ||||
|           nullptr,                                      // const void                     * pNext
 | ||||
|           0,                                            // VkSwapchainCreateFlagsKHR        flags
 | ||||
|           presentation_surface,                         // VkSurfaceKHR                     surface
 | ||||
|           image_count,                                  // uint32_t                         minImageCount
 | ||||
|           surface_format.format,                        // VkFormat                         imageFormat
 | ||||
|           surface_format.colorSpace,                    // VkColorSpaceKHR                  imageColorSpace
 | ||||
|           image_size,                                   // VkExtent2D                       imageExtent
 | ||||
|           1,                                            // uint32_t                         imageArrayLayers
 | ||||
|           image_usage,                                  // VkImageUsageFlags                imageUsage
 | ||||
|           VK_SHARING_MODE_EXCLUSIVE,                    // VkSharingMode                    imageSharingMode
 | ||||
|           0,                                            // uint32_t                         queueFamilyIndexCount
 | ||||
|           nullptr,                                      // const uint32_t                 * pQueueFamilyIndices
 | ||||
|           surface_transform,                            // VkSurfaceTransformFlagBitsKHR    preTransform
 | ||||
|           VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,            // VkCompositeAlphaFlagBitsKHR      compositeAlpha
 | ||||
|           present_mode,                                 // VkPresentModeKHR                 presentMode
 | ||||
|           VK_TRUE,                                      // VkBool32                         clipped
 | ||||
|           old_swapchain                                 // VkSwapchainKHR                   oldSwapchain
 | ||||
|         }; | ||||
| 
 | ||||
|         VkResult result = vkCreateSwapchainKHR(logical_device, &swapchain_create_info, nullptr, &swapchain); | ||||
|         if ((VK_SUCCESS != result) || | ||||
|             (VK_NULL_HANDLE == swapchain)) { | ||||
|             zlog::error("Could not create a swapchain."); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         if (VK_NULL_HANDLE != old_swapchain) { | ||||
|             vkDestroySwapchainKHR(logical_device, old_swapchain, nullptr); | ||||
|             old_swapchain = VK_NULL_HANDLE; | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|     bool GetHandlesOfSwapchainImages(VkDevice               logical_device, | ||||
|         VkSwapchainKHR         swapchain, | ||||
|         std::vector<VkImage>& swapchain_images) { | ||||
|         uint32_t images_count = 0; | ||||
|         VkResult result = VK_SUCCESS; | ||||
| 
 | ||||
|         result = vkGetSwapchainImagesKHR(logical_device, swapchain, &images_count, nullptr); | ||||
|         if ((VK_SUCCESS != result) || | ||||
|             (0 == images_count)) { | ||||
|             zlog::error("Could not get the number of swapchain images."); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         swapchain_images.resize(images_count); | ||||
|         result = vkGetSwapchainImagesKHR(logical_device, swapchain, &images_count, swapchain_images.data()); | ||||
|         if ((VK_SUCCESS != result) || | ||||
|             (0 == images_count)) { | ||||
|             zlog::error("Could not enumerate swapchain images."); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user