Skip to content
Open
40 changes: 26 additions & 14 deletions attachments/17_swap_chain_recreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class HelloTriangleApplication {
glfwInit();

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
Expand Down Expand Up @@ -239,8 +240,9 @@ class HelloTriangleApplication {
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
} );

auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
Expand Down Expand Up @@ -274,11 +276,12 @@ class HelloTriangleApplication {
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
}

// query for Vulkan 1.3 features
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
// query for required features (Vulkan 1.1 and 1.3)
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
Expand Down Expand Up @@ -505,14 +508,23 @@ class HelloTriangleApplication {
queue.submit(submitInfo, *inFlightFences[currentFrame]);


const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
try {
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
}
} catch (const vk::SystemError& e) {
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
recreateSwapChain();
return;
} else {
throw;
}
}
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
Expand Down
40 changes: 26 additions & 14 deletions attachments/18_vertex_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class HelloTriangleApplication {
glfwInit();

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
Expand Down Expand Up @@ -263,8 +264,9 @@ class HelloTriangleApplication {
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
} );

auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
Expand Down Expand Up @@ -298,11 +300,12 @@ class HelloTriangleApplication {
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
}

// query for Vulkan 1.3 features
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
// query for required features (Vulkan 1.1 and 1.3)
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
Expand Down Expand Up @@ -532,14 +535,23 @@ class HelloTriangleApplication {
queue.submit(submitInfo, *inFlightFences[currentFrame]);


const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
try {
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
}
} catch (const vk::SystemError& e) {
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
recreateSwapChain();
return;
} else {
throw;
}
}
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
Expand Down
42 changes: 28 additions & 14 deletions attachments/19_vertex_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class HelloTriangleApplication {
glfwInit();

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
Expand Down Expand Up @@ -267,8 +268,9 @@ class HelloTriangleApplication {
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
} );

auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
Expand Down Expand Up @@ -302,11 +304,12 @@ class HelloTriangleApplication {
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
}

// query for Vulkan 1.3 features
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
// query for required features (Vulkan 1.1 and 1.3)
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
Expand Down Expand Up @@ -344,6 +347,8 @@ class HelloTriangleApplication {
}

void createImageViews() {
swapChainImageViews.clear();

vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format,
.subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } };
for ( auto image : swapChainImages )
Expand Down Expand Up @@ -562,14 +567,23 @@ class HelloTriangleApplication {
queue.submit(submitInfo, *inFlightFences[currentFrame]);


const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
try {
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
}
} catch (const vk::SystemError& e) {
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
recreateSwapChain();
return;
} else {
throw;
}
}
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
Expand Down
41 changes: 27 additions & 14 deletions attachments/20_staging_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class HelloTriangleApplication {
glfwInit();

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
glfwSetWindowUserPointer(window, this);
Expand Down Expand Up @@ -267,8 +268,9 @@ class HelloTriangleApplication {
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
} );

auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
Expand Down Expand Up @@ -302,11 +304,12 @@ class HelloTriangleApplication {
throw std::runtime_error("Could not find a queue for graphics and present -> terminating");
}

// query for Vulkan 1.3 features
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
// query for required features (Vulkan 1.1 and 1.3)
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
{ .shaderDrawParameters = true }, // vk::PhysicalDeviceVulkan11Features
{ .synchronization2 = true, .dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{ .extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
Expand Down Expand Up @@ -344,6 +347,7 @@ class HelloTriangleApplication {
}

void createImageViews() {
swapChainImageViews.clear();
vk::ImageViewCreateInfo imageViewCreateInfo{ .viewType = vk::ImageViewType::e2D, .format = swapChainSurfaceFormat.format,
.subresourceRange = { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 } };
for ( auto image : swapChainImages )
Expand Down Expand Up @@ -581,14 +585,23 @@ class HelloTriangleApplication {
queue.submit(submitInfo, *inFlightFences[currentFrame]);


const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
try {
const vk::PresentInfoKHR presentInfoKHR{ .waitSemaphoreCount = 1, .pWaitSemaphores = &*renderFinishedSemaphore[imageIndex],
.swapchainCount = 1, .pSwapchains = &*swapChain, .pImageIndices = &imageIndex };
result = queue.presentKHR( presentInfoKHR );
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
framebufferResized = false;
recreateSwapChain();
} else if (result != vk::Result::eSuccess) {
throw std::runtime_error("failed to present swap chain image!");
}
} catch (const vk::SystemError& e) {
if (e.code().value() == static_cast<int>(vk::Result::eErrorOutOfDateKHR)) {
recreateSwapChain();
return;
} else {
throw;
}
}
semaphoreIndex = (semaphoreIndex + 1) % presentCompleteSemaphore.size();
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
Expand Down
Loading
Loading