<aside> 💡 Vulkan Tutorial 영어 원문
</aside>
그리기 작업이나 메모리 전송 등의 Vulkan 명령들은 함수 호출로 직접 실행되지 않습니다. 명령 버퍼 객체에서 수행하려는 모든 작업을 기록해야 합니다. 이 장점은 Vulkan에게 우리가 하고 싶은 것을 말할 준비가 되었을 때, 모든 명령이 함께 제출되고 Vulkan은 모든 명령을 함께 사용할 수 있기 때문에 보다 효율적인 작업을 할 수 있습니다. 또한 원한다면 여러 쓰레드에서 명령 기록을 수행할 수 있습니다.
명령 버퍼를 만들기 전에 명령 풀을 만들어야 합니다. 명령 풀은 버퍼를 저장하는데 사용되는 메모리를 관리하고, 명령 버퍼를 할당합니다. VkCommandPool를 저장할 새로운 클래스 멤버를 추가합니다:
VkCommandPool commandPool;
그 다음 새로운 함수 createCommandPool를 만들고 initVulkan에서 프레임버퍼가 생성된 이후에 호출합니다.
void initVulkan() {
createInstance();
setupDebugMessenger();
createSurface();
pickPhysicalDevice();
createLogicalDevice();
createSwapChain();
createImageViews();
createRenderPass();
createGraphicsPipeline();
createFramebuffers();
createCommandPool();
}
...
void createCommandPool() {
}
명령 버퍼를 생성할 때는 두 매개변수만 사용합니다:
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
명령 풀에는 두가지 플래그가 있습니다:
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT: 명령 버퍼가 새 명령으로 자주 기록된다는 힌트 (메모리 할당 동작이 변경될 수 있음)VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT: 명령 버퍼가 개별적으로 다시 기록되도록 허용. 이 플래그가 없으면 모두 재설정해야 함.우리는 매 프레임마다 커멘드 버퍼를 기록할 것이기 때문에, 리셋하고 다시 기록하길 원합니다. 그러므로 우리의 커멘드 풀에는 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT 플래그를 설정해야 합니다.
명령 버퍼는 우리가 검색한 그래픽과 프레젠테이션 큐 같은 장치 큐 중의 하나에 제출되어 실행됩니다. 각 명령 풀은 단일 유형의 큐에 제출된 명령 버퍼만 할당할 수 있습니다. 그리기 명령을 기록할 것이므로, 그래픽 큐 패밀리를 선택했습니다.
if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create command pool!");
}
명령 풀 생성을 vkCreateCommandPool 함수를 사용하여 끝냅니다. 특별한 매게변수가 필요없습니다. 명령은 프로그램 전반에서 화면에 무언가를 그리는데 사용되므로, 마지막에 파괴되어야 합니다:
void cleanup() {
vkDestroyCommandPool(device, commandPool, nullptr);
...
}
이제 명령 버퍼 할당을 시작할 수 있습니다.
클래스 멤버로 VkCreateBuffer 객체를 만듭니다. 명령 버퍼는 명령 풀이 파괴될 때 자동으로 해제되므로 명시적 정리가 필요하지 않습니다.