1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef VULKAN_EXAMPLE_H 17 #define VULKAN_EXAMPLE_H 18 #include "vulkan/vulkan.h" 19 #include "logger_common.h" 20 #include "vulkan_utils.h" 21 #include <native_window/external_window.h> 22 #include <iostream> 23 #include <fstream> 24 #include <stdexcept> 25 #include <algorithm> 26 #include <vector> 27 #include <cstring> 28 #include <cstdlib> 29 #include <cstdint> 30 #include <limits> 31 #include <optional> 32 #include <set> 33 namespace vkExample { 34 struct QueueFamilyIndices { 35 int graphicsFamily = -1; 36 int presentFamily = -1; 37 IsCompleteQueueFamilyIndices38 bool IsComplete() 39 { 40 return graphicsFamily >= 0 && presentFamily >= 0; 41 } 42 }; 43 44 struct SwapChainSupportDetails { 45 VkSurfaceCapabilitiesKHR capabilities; 46 std::vector<VkSurfaceFormatKHR> formats; 47 std::vector<VkPresentModeKHR> presentModes; 48 }; 49 50 class VulkanExample { 51 public: 52 VulkanExample(); 53 ~VulkanExample(); 54 bool InitVulkan(); 55 void SetupWindow(NativeWindow* nativeWindow); 56 void SetUp(); 57 void RenderLoop(); 58 bool IsInited() const; 59 void SetRecreateSwapChain(); 60 private: 61 bool CreateInstance(); 62 bool CreateSurface(); 63 bool CreateLogicalDevice(); 64 void CreateSwapChain(); 65 void CreateImageViews(); 66 void CreateRenderPass(); 67 void CreateDescriptorSetLayout(); 68 void CreateGraphicsPipeline(); 69 void CreateFramebuffers(); 70 void CreateCommandPool(); 71 uint32_t GetMemoryTypeIndex(uint32_t typeFilter, VkMemoryPropertyFlags properties); 72 void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, 73 VkBuffer &buffer, VkDeviceMemory &bufferMemory); 74 void CreateVertices(); 75 void UpdateVertices(); 76 void CreateUniformBuffers(); 77 void CreateDescriptorPool(); 78 void CreateDescriptorSets(); 79 void CreateCommandBuffer(); 80 void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); 81 void CreateSyncObjects(); 82 void UpdateUniformBuffers(); 83 void CleanupSwapChain(); 84 void RecreateSwapChain(); 85 void DrawFrame(); 86 bool PickPhysicalDevice(); 87 VkShaderModule CreateShaderModule(const std::vector<char> &code); 88 VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats); 89 VkPresentModeKHR ChooseSwapPresentMode(const std::vector<VkPresentModeKHR> &availablePresentModes); 90 VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities); 91 SwapChainSupportDetails QuerySwapChainSupport(VkPhysicalDevice device); 92 bool IsDeviceSuitable(VkPhysicalDevice device); 93 bool CheckDeviceExtensionSupport(VkPhysicalDevice device); 94 QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device); 95 std::vector<const char *> GetRequiredExtensions(); 96 VkShaderModule LoadSPIRVShader(std::string filename); 97 VkCommandBuffer GetCommandBuffer(); 98 void FlushCommandBuffer(VkCommandBuffer commandBuffer); 99 VkPipelineVertexInputStateCreateInfo PrepareVertexInputState( 100 VkVertexInputBindingDescription& vertexInputBinding, 101 // 2 attributes for position(location = 0) and color (location = 1) 102 std::array<VkVertexInputAttributeDescription, 2>& vertexInputAttributes); 103 VkPipelineColorBlendStateCreateInfo PrepareColorBlendState( 104 VkPipelineColorBlendAttachmentState& blendAttachmentState); 105 VkPipelineInputAssemblyStateCreateInfo PrepareInputAssemblyState(); 106 VkPipelineRasterizationStateCreateInfo PrepareRasterizationState(); 107 VkPipelineMultisampleStateCreateInfo PrepareMultisampleState(); 108 VkPipelineViewportStateCreateInfo PrepareViewportState(); 109 void PreparePipelineLayout(); 110 VkPipelineDynamicStateCreateInfo PrepareDynamicState(std::vector<VkDynamicState>& dynamicStates); 111 112 struct Vertex { 113 float position[3]; 114 float color[3]; 115 }; 116 117 struct VulkanBuffer { 118 VkDeviceMemory memory; 119 VkBuffer buffer; 120 }; 121 122 // mvp matrix 123 struct { 124 float mat[4][4] = {{0.974279, 0.000000, 0.000000, 0.000000}, 125 {0.000000, 1.732051, 0.000000, 0.000000}, 126 {0.000000, 0.000000, -1.003922, -1.000000}, 127 {0.000000, 0.000000, 1.505882, 2.500000}}; 128 } uboVS; 129 float alpha = 0.0f; 130 std::vector<Vertex> vertices = {{{std::sin(alpha), 1.0f, -std::cos(alpha)}, {1.0f, 0.0f, 0.0f}}, 131 {{-std::sin(alpha), 1.0f, std::cos(alpha)}, {0.0f, 1.0f, 0.0f}}, 132 {{0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}}; 133 std::vector<uint32_t> indices = {0, 1, 2}; 134 VkDeviceSize vertexBufferSize = vertices.size() * sizeof(Vertex); 135 VkDeviceSize indexBufferSize = indices.size() * sizeof(uint32_t); 136 uint32_t width = 1280; 137 uint32_t height = 720; 138 bool inited = false; 139 bool shouldRecreate = false; 140 const std::vector<const char *> deviceExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; 141 std::vector<std::string> supportedInstanceExtensions; 142 std::vector<const char *> enabledInstanceExtensions; 143 144 NativeWindow *window = nullptr; 145 146 VkInstance instance; 147 VkDebugUtilsMessengerEXT debugMessenger; 148 VkSurfaceKHR surface; 149 150 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; 151 VkDevice device; 152 153 VkQueue graphicsQueue; 154 VkQueue presentQueue; 155 156 VkSwapchainKHR swapChain; 157 std::vector<VkImage> swapChainImages; 158 VkFormat swapChainImageFormat; 159 VkExtent2D swapChainExtent; 160 std::vector<VkImageView> swapChainImageViews; 161 std::vector<VkFramebuffer> swapChainFramebuffers; 162 163 VkRenderPass renderPass; 164 VkPipelineLayout pipelineLayout; 165 VkPipeline graphicsPipeline; 166 167 VkCommandPool commandPool; 168 VkCommandBuffer commandBuffer; 169 170 VkSemaphore imageAvailableSemaphore; 171 VkSemaphore renderFinishedSemaphore; 172 VkFence inFlightFence; 173 174 VulkanBuffer vertexBuffer; 175 VulkanBuffer indexBuffer; 176 VulkanBuffer uniformBuffer; 177 VulkanBuffer vertexStagingBuffer; 178 VulkanBuffer indexStagingBuffer; 179 180 VkDescriptorSetLayout descriptorSetLayout; 181 VkDescriptorPool descriptorPool; 182 VkDescriptorSet descriptorSet; 183 }; 184 } // namespace vkExample 185 #endif //VULKAN_EXAMPLE_H