์ฐฝ ํฌ๊ธฐ ์ฌ์กฐ์ ํ๊ธฐ
Vulkan์์๋ ์ฐฝ ํฌ๊ธฐ ์กฐ์ ์ ์ง์ ์ฒ๋ฆฌํด ์ฃผ์ด์ผ ํฉ๋๋ค. 0์ฅ์์ ์ด๋ฏธ ์ฐฝ์ด ์ต์ํ๋์์ ๋๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋๋ฅผ ์์ฑํ์ง๋ง, ์ฐฝ ํฌ๊ธฐ ์กฐ์ ์ ํจ์ฌ ๋ ๋ณต์กํ ์์ ์ ๋๋ค.
์ฐฝ ํฌ๊ธฐ๊ฐ ์กฐ์ ๋ ๋ ์ค์์ฒด์ธ์ ๋ ์ด์ ์ ํจํ์ง ์๊ฒ ๋๋ฉฐ, vkAcquireNextImageKHR
, vkQueuePresentKHR
๊ณผ ๊ฐ์ Vulkan์ ์ค์์ฒด์ธ ๋ช
๋ น์ VK_ERROR_OUT_OF_DATE_KHR
์ค๋ฅ๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ์ฌ ์ค์์ฒด์ธ์ ์๋ก์ด ํฌ๊ธฐ๋ก ์ฌ์์ฑํ๊ฒ ํด์ผ ํฉ๋๋ค.
ํจ์จ์ฑ์ ์ํด drawImage๋ฅผ ์ฌํ ๋นํ์ง๋ ์์ ๊ฒ์ ๋๋ค. ์ง๊ธ ๋น์ฅ์ drawImage์ depthImage๋ง์ ๊ฐ์ง๋ง ์กฐ๊ธ ๋ ๊ณ ๋ํ๋ ์์ง์์๋ ์๋นํ ๋ง์ ์ด๋ฏธ์ง๊ฐ ์์ ๊ฒ์ด๋ฉฐ ์ด ๋ชจ๋ ๊ฒ์ ์ฌ์์ฑํ๋ ๊ฒ์ ๋ฒ๊ฑฐ๋กญ๊ณ ๋น์ฉ์ด ํฝ๋๋ค. ๋์ , drawImage์ depthImage๋ฅผ ์์ ์ ํ๋ฆฌ์ ๋ ํฌ๊ธฐ๋ก ์์ฑํด ์ฐฝ์ด ์์ ๊ฒฝ์ฐ ํด๋น ์ด๋ฏธ์ง์ ์ผ๋ถ๋ถ์ ๋ ๋๋งํ๊ณ , ์ฐฝ์ด ์ปค์ง๋ฉด ๋ ๋์ ์์ญ์ ๋ ๋๋งํ๋๋ก ํฉ๋๋ค. ์ด๋ฏธ์ง๋ฅผ ์ฌํ ๋นํ์ง ์๊ณ ๊ตฌ์์๋ง ๋ ๋๋งํ๊ธฐ ๋๋ฌธ์ ์ด ๋ก์ง์ ๋์ ํด์๋ ๊ตฌํ์๋ ์์ฉํ ์ ์์ต๋๋ค. ๋์ ํด์๋๋ ์ฑ๋ฅ์ ์ ์ฐํ๊ฒ ์กฐ์ ํ ์ ์๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ฉฐ, ๋๋ฒ๊น ์์๋ ์ ์ฉํ๊ฒ ํ์ฉํ ์ ์์ต๋๋ค. ํ์ฌ drawImage์์ ์ค์์ฒด์ธ ์ด๋ฏธ์ง๋ก VkCmdBlit์ ์ฌ์ฉํด ๋ณต์ฌํ๊ณ ์์ผ๋ฉฐ, ์ด ์ฐ์ฐ์ ํ๋ ์ถ์๋ฅผ ์ํํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ฐฉ์์์๋ ์ ์๋ํ ๊ฒ์ ๋๋ค. ๋ฌผ๋ก ์ด๋ฌํ ๋ฐฉ์์ ํ๋ ์ถ์๋ ์ต๊ณ ํ์ง์ ์๋๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ ํ๋ ์ sharpening๊ฐ์ ์ถ๊ฐ ํํฐ๋ฅผ ์ ์ํ๊ฑฐ๋, ์ํฐ์จ๋ฆฌ์ด์ฑ ํจ๊ณผ๋ฅผ ํ๋ด๋ด๋ ๋ฑ์ ๋ณต์กํ ์ฒ๋ฆฌ๊ฐ ๋ํด์ ธ์ผ ์ข์ ํ์ง์ ์ป์ ์ ์์ต๋๋ค. ImGui UI๋ ์ฌ์ ํ ์ค์์ฒด์ธ ์ด๋ฏธ์ง์ ์ง์ ๊ทธ๋ฆด ๊ฒ์ด๋ฏ๋ก, ํญ์ ๋ค์ดํฐ๋ธ ํด์๋๋ก ๋ ๋๋งํ ๊ฒ์ ๋๋ค.
์ด์ ์ฐฝ ์์ฑ ์ ์ฐฝ ํฌ๊ธฐ ์กฐ์ ๊ฐ๋ฅ(resizable) ํ๋๊ทธ๋ฅผ ํ์ฑํํด๋ด ์๋ค. ๊ทธํ ์ค์ ๋ก ์ฐฝ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํด ๋ณด๋ฉด ์ด๋ค ์ผ์ด ์ผ์ด๋๋์ง ํ์ธํด๋ณผ ์ ์์ต๋๋ค.
VulkanEngine::init
์ ์๋จ์ window_flags๋ฅผ ๋ฐ๊พธ์ด resizable ํ๋๊ทธ๋ฅผ ๊ฐ๋๋ก ํฉ๋๋ค.
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
SDL์ ์ฐฝ ํฌ๊ธฐ ์กฐ์ ๊ณผ ๊ด๋ จ๋ ์ด์์ฒด์ ๋ ๋ฒจ์ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ฏ๋ก, ์ง๊ธ ๋น์ฅ ์ฐฝ ํฌ๊ธฐ ์กฐ์ ์ ์๋ํด๋ณผ ์ ์์ต๋๋ค. ์์ง์ ์คํํด ์ฐฝ์ ์ฌ์กฐ์ ํด๋ด ์๋ค.
์ด ์์
์ ํ๋ฉด vkAcquireNextImageKHR
ํน์ vkQueuePresentKHR
์ค ํ๋์์ VK_CHECK ๋งคํฌ๋ก๊ฐ ์๋ฌ๋ฅผ ๊ฐ์งํ๊ณ ํฌ๋์๊ฐ ๋ฐ์ํ ๊ฒ์
๋๋ค. ๋ฐ์ํ๋ ์๋ฌ๋ VK_ERROR_OUT_OF_DATE_KHR
์ผ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค. ๋ฐ๋ผ์ ์ด ์๋ฌ๋ฅผ ์ ๋๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด, ํด๋น ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ๋ ๋๋ง์ ์ค๋จํ๊ณ ์ค์์ฒด์ธ์ ๋ค์ ์์ฑํด ์ฃผ์ด์ผ ํฉ๋๋ค.
๋จผ์ , VulkanEngine ํด๋์ค์ resize_requested
๋ผ๋ ์ด๋ฆ์ bool ๋ณ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.
draw()ํจ์์ vkAcquireNextImageKHR
ํธ์ถ์ ์๋ฌ ์ฝ๋๋ฅผ ํ์ธํ๋ ์ฝ๋๋ก ๋์ฒดํฉ๋๋ค.
VkResult e = vkAcquireNextImageKHR(_device, _swapchain, 1000000000, get_current_frame()._swapchainSemaphore, nullptr, &swapchainImageIndex);
if (e == VK_ERROR_OUT_OF_DATE_KHR) {
resize_requested = true;
return ;
}
๋ํ vkQueuePresentKHR
๋ ๋์ผํ๊ฒ ๋์ฒดํฉ๋๋ค. ํ์ง๋ง ์ด๋ฏธ ํจ์์ ๋์ด๊ธฐ ๋๋ฌธ์ return
์ ํ์ง ์์ต๋๋ค.
VkResult presentResult = vkQueuePresentKHR(_graphicsQueue, &presentInfo);
if (presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
resize_requested = true;
}
์ด์ ํด๋น ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ๋ ๋๋ง์ ์ค๋จํ๊ฒ ๋๋ฏ๋ก, ์ฐฝ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํด๋ ํฌ๋์๋ ๋ฐ์ํ์ง ์๊ฒ ์ง๋ง, ํ๋ฉด์ด ๋ค์ ๊ทธ๋ ค์ง์ง ์๊ณ ์ด๋ฏธ์ง๊ฐ ๋ฉ์ถ ์ํ๋ก ์ ์ง๋ ๊ฒ์ ๋๋ค.
resize_swapchain()
ํจ์๋ฅผ ์ถ๊ฐํ์ฌ VulkanEngine์ด ์ค์์ฒด์ธ์ ์ฌ์์ฑํ๋๋ก ํฉ์๋ค.
void VulkanEngine::resize_swapchain()
{
vkDeviceWaitIdle(_device);
destroy_swapchain();
int w, h;
SDL_GetWindowSize(_window, &w, &h);
_windowExtent.width = w;
_windowExtent.height = h;
create_swapchain(_windowExtent.width, _windowExtent.height);
resize_requested = false;
}
์ค์์ฒด์ธ์ ์ฌ์์ฑํ๊ธฐ ์ํด GPU๊ฐ ๋ชจ๋ ๋ ๋๋ง ์์ ์ ์๋ฃํ ๋ ๊น์ง ๋๊ธฐํด์ผ ํฉ๋๋ค. GPU๊ฐ ์ฌ์ ํ ์ด๋ฏธ์ง์ ์ด๋ฏธ์ง ๋ทฐ๋ฅผ ์ฌ์ฉ์ค์ผ ์ ์๊ธฐ ๋๋ฌธ์, ๊ทธ ์ํ์์ ๋ณ๊ฒฝํด์๋ ์๋ฉ๋๋ค. ๊ทธํ ์ค์์ฒด์ธ์ ํ๊ดดํ๊ณ SDL๋ก๋ถํฐ ์ฐฝํฌ๊ธฐ๋ฅผ ์กฐํํ์ฌ ๊ทธ์ ๋ง๊ฒ ์๋ก ์์ฑํฉ๋๋ค.
์ด์ run() ๋ฐ๋ณต๋ฌธ์์ ์ด๋ฏธ์ง๊ฐ ์ฌ์กฐ์ ๋ ๋ ์ด ํจ์๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค.
SDL ์ด๋ฒคํธ ๋ฃจํ์ freeze_rendering ํ์ธ ์ดํ, ์๋ก์ด ImGui ํ๋ ์์ ์์ํ๋ ํจ์๋ค๋ณด๋ค ๋จผ์ ์ด ํจ์๋ฅผ ํธ์ถํ๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
if (resize_requested) {
resize_swapchain();
}
์ด์ ์ฌ์กฐ์ ๊ธฐ๋ฅ์ด ๊ตฌํ๋์์ผ๋ ํ๋ฒ ์๋ํด๋ณด์ธ์. ์ด์ ์๋ฌ ์์ด ์ด๋ฏธ์ง ์ถ์๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ํ์ง๋ง ์ฐฝ์ ๋ ํฌ๊ฒ ๋ง๋ ๋ค๋ฉด ์คํจํ ๊ฒ์ ๋๋ค. drawImage ์์ญ ๋ฐ์ผ๋ก ๋ ๋๋งํ๋ ค๊ณ ์๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด ๋ฌธ์ ๋ _drawExtent ๋ณ์๋ฅผ ๋์ ํ๊ณ ํด๋น ๋ณ์๊ฐ drawImage ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ์ง ์๋๋ก ์ค์ ํจ์ผ๋ก์จ ํด๊ฒฐํ ์ ์์ต๋๋ค.
_drawExtent
์ ๋์ ํด์๋ ์กฐ์ ์ ์ํด ์ฌ์ฉํ renderScale
float๋ฅผ VulkanEngine ํด๋์ค์ ์ถ๊ฐํด์ค๋๋ค.
VkExtent2D _drawExtent;
float renderScale = 1.f;
draw() ํจ์๋ก ๋์์ ์์ํ ๋ ๊ธฐ์กด์ drawImage Extent๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ ๋์ drawExtent๋ฅผ ๊ณ์ฐํ๋๋ก ํฉ๋๋ค.
_drawExtent.height = std::min(_swapchainExtent.height, _drawImage.imageExtent.height) * renderScale;
_drawExtent.width= std::min(_swapchainExtent.width, _drawImage.imageExtent.width) * renderScale;
์ด์ ImGui์ ์ฌ๋ผ์ด๋๋ฅผ ์ถ๊ฐํด drawScale ํ๋ผ๋ฏธํฐ๋ฅผ ์ ์ดํ ์ ์๋๋ก ํ๊ฒ ์ต๋๋ค.
run()
ํจ์์์ ๋ฐฐ๊ฒฝ ๊ด๋ จ ํ๋ผ๋ฏธํฐ๋ฅผ ์ค์ ํ๋ ImGui ์ฐฝ ๋ด๋ถ์ ์๋จ์ ์ด ์ฌ๋ผ์ด๋ ์ฝ๋๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
if (ImGui::Begin("background")) {
ImGui::SliderFloat("Render Scale",&renderScale, 0.3f, 1.f);
//other code
}
์ด๋ 0.3์์ 1.0๊น์ง์ ๋ ๋๋ง ๋ฐฐ์จ์ ์กฐ์ ํ ์ ์๋ ์ฌ๋ผ์ด๋์ ๋๋ค. 1์ ์ด๊ณผํ๋ฉด ํด์๋๋ฅผ ๊นจํธ๋ฆด ์ ์๊ธฐ ๋๋ฌธ์ ์ ํํฉ๋๋ค.
ํ๋ก๊ทธ๋จ์ ์คํํด ์ฐฝ ํฌ๊ธฐ๋ฅผ ์ฌ์กฐ์ ํ๊ณ ๋ ๋๋ง ๋ฐฐ์จ์ ์กฐ์ ํด๋ณด์ธ์. ์ด์ ๋์ ์ผ๋ก ํด์๋๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ฐฝ์ ์ต๋ํํ๊ฑฐ๋ ์ด๋ํ ์ ์์ต๋๋ค.
ํ์ฌ drawImage๋ฅผ ๋ค์ ์์ ํฌ๊ธฐ๋ก ์ค์ ํ์ง๋ง ์ํ๋ค๋ฉด init_swapchain()์์ ์์ฑ๋๋ drawImage์ ํฌ๊ธฐ๋ฅผ ํค์๋ณผ ์๋ ์์ต๋๋ค. _windowExntent ๋์ ๋ชจ๋ํฐ ํด์๋๋ฅผ drawImageExtent
์ ์ง์ ์ง์ ํด๋ณด์ธ์.
์ด๊ฒ์ผ๋ก 3์ฅ์ด ๋๋ฌ์ต๋๋ค. ์ด์ ๋ค์ ์ฅ์ผ๋ก ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
Next: Chapter 4: New Descriptor Abstractions