-
Notifications
You must be signed in to change notification settings - Fork 0
/
lve_device.hpp
276 lines (239 loc) · 7.87 KB
/
lve_device.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#pragma once
#include "lve_window.hpp"
// std lib headers
#include <string>
#include <vector>
namespace lve {
struct SwapChainSupportDetails {
VkSurfaceCapabilitiesKHR capabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentModes;
};
struct QueueFamilyIndices {
uint32_t graphicsFamily;
uint32_t presentFamily;
bool graphicsFamilyHasValue = false;
bool presentFamilyHasValue = false;
bool isComplete() { return graphicsFamilyHasValue && presentFamilyHasValue; }
};
/**
* @brief device instance 생성
*
* Vulkan Instance 설정, 디버그 메세지 설정 , glfw와 surface 연결
* Physical Device 선택, Logical Device 설정, CommandPool 생성
*/
class LveDevice {
public:
/**
* @brief 배포할 때에는 디버그 레이어를 끄고, 개발할 때에는 켠다
*
*/
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif
LveDevice(LveWindow &window);
~LveDevice();
// Not copyable or movable
LveDevice(const LveDevice &) = delete;
LveDevice operator=(const LveDevice &) = delete;
LveDevice(LveDevice &&) = delete;
LveDevice &operator=(LveDevice &&) = delete;
// getter function
VkCommandPool getCommandPool() { return commandPool; }
VkDevice device() { return device_; }
VkSurfaceKHR surface() { return surface_; }
VkQueue graphicsQueue() { return graphicsQueue_; }
VkQueue presentQueue() { return presentQueue_; }
SwapChainSupportDetails getSwapChainSupport() {
return querySwapChainSupport(physicalDevice);
}
QueueFamilyIndices findPhysicalQueueFamilies() {
return findQueueFamilies(physicalDevice);
}
/**
* @brief Vulkan에서 메모리 할당을 위한 메모리 유형을 선택
*
* @param typeFilter 특정 메모리 유형 비트를 나타내는 필터
* @param properties 필요한 메모리 속성 플래그(VkMemoryPropertyFlags)
* @return uint32_t
*/
uint32_t findMemoryType(uint32_t typeFilter,
VkMemoryPropertyFlags properties);
/**
* @brief Vulkan 애플리케이션에서 특정 텍스처나 이미지에 필요한
* 형식(format)을 찾기 위해 사용
*
* @param candidates 사용할 수 있는 형식 목록
* @param tiling 이미지 타일링 방식 설정
* @param features 요구되는 형식 기능 플래그
* @return VkFormat
*/
VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates,
VkImageTiling tiling,
VkFormatFeatureFlags features);
/**
* @brief Vulkan에서 버퍼를 생성하고 필요한 메모리를 할당
*
* @param size 버퍼의 크기
* @param usage 버퍼의 사용 용도
* @param properties 할당할 메모리의 속성 지정
* @param buffer 버퍼 객체
* @param bufferMemory 버퍼에 할당된 메모리를 가리킴
*/
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties, VkBuffer &buffer,
VkDeviceMemory &bufferMemory);
/**
* @brief 간단한 작업을 위해 일회성 커맨드 버퍼를 생성하고 시작
*/
VkCommandBuffer beginSingleTimeCommands();
/**
* @brief 한 일회성 커맨드 버퍼를 완료하고 command pool에 제출
*
* @param commandBuffer
*/
void endSingleTimeCommands(VkCommandBuffer commandBuffer);
/**
* @brief 한 버퍼의 데이터를 다른 버퍼로 복사
*
* @param srcBuffer 원본 버퍼
* @param dstBuffer 대상 버퍼
* @param size 버퍼 크기
*/
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
/**
* @brief 텍스처 이미지 데이터를 CPU에서 준비하여 GPU로 복사할 때 사용
* 이미지를 CPU에서 로드 -> 그 데이터를 Vulkan 버퍼에 저장
* -> 이 데이터를 GPU에서 텍스처로 사용 할수 있도록 이미지 리소스로 복사
*
* @param buffer 원본 버퍼
* @param image 복사 대상 이미지
* @param width
* @param height
* @param layerCount 복사할 이미지의 레이어 수
*/
void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width,
uint32_t height, uint32_t layerCount);
/**
* @brief 이미지 리소스를 생성할 때, 메모리 할당과 바인딩을 명시
*
* @param imageInfo 이미지 생성 정보
* @param properties 할당할 메모리의 속성
* @param image 생성된 이미지 객체
* @param imageMemory 이미지에 할당된 메모리
*/
void createImageWithInfo(const VkImageCreateInfo &imageInfo,
VkMemoryPropertyFlags properties, VkImage &image,
VkDeviceMemory &imageMemory);
/**
* @brief 물리적 장치의 특성 정보를 저장
*/
VkPhysicalDeviceProperties properties;
private:
/**
* @brief 유효성 검사 레이어 설정, 애플리케이션과 vulkan 연결 instance 생성
*
*/
void createInstance();
/**
* @brief Debug 메시지 설정
*
*/
void setupDebugMessenger();
/**
* @brief glfw에서 vulkan을 사용할 수 있도록 surface(window) 생성
*
*/
void createSurface();
//
/**
* @brief 애플리케이션이 사용하는 물리적 장치 선택
* ex: 3060ti, 3080, 3090, 등등, 복수 선택도 가능은 함
*
*/
void pickPhysicalDevice();
/**
* @brief 우리가 사용하려는 물리적 장치의 기능을 설명
*
*/
void createLogicalDevice();
/**
* @brief 나중에 사용하는 명령어 pool을 만들어 놓기
*
*/
void createCommandPool();
/**
* @brief Vulkan이 사용할 GPU가 특정 요구 사항을 충족하는지 검사
*
* @param device
* @return boolean
*/
bool isDeviceSuitable(VkPhysicalDevice device);
/**
* @brief Vulkan 애플리케이션이 실행되기 위해 필요한 확장목록을 반환
* -> 필요한 확장이 있으면 추가해도 됨
*
* @return std::vector<const char *>
*/
std::vector<const char *> getRequiredExtensions();
/**
* @brief 주어진 물리적 장치가 필요한 확장을 지원하는지 확인
*
* @param device
* @return boolean
*/
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
/**
* @brief 요청된 유효성 검사 레이어들이 운영체제에서 지원되는지 확인
*
* @return boolean
*/
bool checkValidationLayerSupport();
/**
* @brief 필요한 인스턴스 확장 기능을 운영체제에서 지원하는지 확인하는 함수
*
*/
void hasGflwRequiredInstanceExtensions();
/**
* @brief Vulkan 애플리케이션이 선택된 물리적 디바이스에서 사용할 수 있는 큐
* 패밀리(queue family)를 찾음
*
* @param device
* @return QueueFamilyIndices
*/
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
/**
* @brief 디버그 메시지 설정을 위한 디버깅 구조체 초기화
*
* @param createInfo
*/
void populateDebugMessengerCreateInfo(
VkDebugUtilsMessengerCreateInfoEXT &createInfo);
/**
* @brief 물리적 장치의 swap chain 지원 정보를 반환
*
* @param device
* @return SwapChainSupportDetails
*/
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
// Vulkan 객체들 (인스턴스, 디바이스, 명령 풀 등)
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
LveWindow &window;
VkCommandPool commandPool;
VkDevice device_;
VkSurfaceKHR surface_;
VkQueue graphicsQueue_;
VkQueue presentQueue_;
// validation layer 설정
const std::vector<const char *> validationLayers = {
"VK_LAYER_KHRONOS_validation"};
const std::vector<const char *> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
"VK_KHR_portability_subset",
};
};
} // namespace lve