• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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