Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion attachments/03_physical_device_selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand Down
31 changes: 17 additions & 14 deletions attachments/04_logical_device.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <assert.h>
#include <iostream>
#include <stdexcept>
#include <vector>
Expand Down Expand Up @@ -170,7 +171,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand All @@ -191,25 +192,27 @@ class HelloTriangleApplication {
// get the first index into queueFamilyProperties which supports graphics
auto graphicsQueueFamilyProperty = std::ranges::find_if( queueFamilyProperties, []( auto const & qfp )
{ return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0); } );
assert(graphicsQueueFamilyProperty != queueFamilyProperties.end() && "No graphics queue family found!");

auto graphicsIndex = static_cast<uint32_t>( std::distance( queueFamilyProperties.begin(), graphicsQueueFamilyProperty ) );

// query for Vulkan 1.3 features
auto features = physicalDevice.getFeatures2();
vk::PhysicalDeviceVulkan13Features vulkan13Features;
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
vulkan13Features.dynamicRendering = vk::True;
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
vulkan13Features.pNext = &extendedDynamicStateFeatures;
features.pNext = &vulkan13Features;
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's really cool, I didn't even know this was available. We should also find a place in the tutorial text to call this out, describe pros/cons and recommend it. If you'd like go ahead and add this to the rest of the chapters and I'm happy to draft the language in the tutorial itself unless you wanna do that?

Copy link
Copy Markdown
Contributor Author

@asuessenbach asuessenbach Jul 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you'd like go ahead and add this to the rest of the chapters

With "this", you mean the approach right above?
I also like that one a little more, even though it needs that vk::PhysicalDeviceFeatures2 as an anchor for the structs, which isn't used besides that.
The other approach doesn't need that struct, the feature structs are simply chained to vk::DeviceCreateInfo.

I'm happy to draft the language in the tutorial itself

Sounds good.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, i meant the first approach. For some reason to my eye it still looks cleaner even if it requires an extra struct rather than directly to the device create info. Maybe because it feels closer to what I'm used to with the C version to use the extra struct or at least kinda follow what I'm expecting.

// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
deviceCreateInfo.enabledExtensionCount = requiredDeviceExtension.size();
deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtension.data();

device = vk::raii::Device( physicalDevice, deviceCreateInfo );
vk::DeviceQueueCreateInfo deviceQueueCreateInfo{ .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>(),
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data() };

device = vk::raii::Device(physicalDevice, deviceCreateInfo);
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
}

Expand Down
25 changes: 13 additions & 12 deletions attachments/05_window_surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand Down Expand Up @@ -244,19 +244,20 @@ class HelloTriangleApplication {
}

// query for Vulkan 1.3 features
auto features = physicalDevice.getFeatures2();
vk::PhysicalDeviceVulkan13Features vulkan13Features;
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
vulkan13Features.dynamicRendering = vk::True;
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
vulkan13Features.pNext = &extendedDynamicStateFeatures;
features.pNext = &vulkan13Features;
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
deviceCreateInfo.enabledExtensionCount = requiredDeviceExtension.size();
deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtension.data();
vk::DeviceQueueCreateInfo deviceQueueCreateInfo{ .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>(),
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data() };

device = vk::raii::Device( physicalDevice, deviceCreateInfo );
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
Expand Down
29 changes: 13 additions & 16 deletions attachments/06_swap_chain_creation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand Down Expand Up @@ -252,23 +252,20 @@ class HelloTriangleApplication {
}

// query for Vulkan 1.3 features
auto features = physicalDevice.getFeatures2();
vk::PhysicalDeviceVulkan13Features vulkan13Features;
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
vulkan13Features.dynamicRendering = vk::True;
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
vulkan13Features.pNext = &extendedDynamicStateFeatures;
features.pNext = &vulkan13Features;
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{
.pNext = &features,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data()
};
vk::DeviceQueueCreateInfo deviceQueueCreateInfo{ .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>(),
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data() };

device = vk::raii::Device( physicalDevice, deviceCreateInfo );
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
Expand Down
29 changes: 13 additions & 16 deletions attachments/07_image_views.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand Down Expand Up @@ -253,23 +253,20 @@ class HelloTriangleApplication {
}

// query for Vulkan 1.3 features
auto features = physicalDevice.getFeatures2();
vk::PhysicalDeviceVulkan13Features vulkan13Features;
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
vulkan13Features.dynamicRendering = vk::True;
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
vulkan13Features.pNext = &extendedDynamicStateFeatures;
features.pNext = &vulkan13Features;
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{
.pNext = &features,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data()
};
vk::DeviceQueueCreateInfo deviceQueueCreateInfo{ .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>(),
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data() };

device = vk::raii::Device( physicalDevice, deviceCreateInfo );
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
Expand Down
29 changes: 13 additions & 16 deletions attachments/08_graphics_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class HelloTriangleApplication {

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

return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
} );
Expand Down Expand Up @@ -254,23 +254,20 @@ class HelloTriangleApplication {
}

// query for Vulkan 1.3 features
auto features = physicalDevice.getFeatures2();
vk::PhysicalDeviceVulkan13Features vulkan13Features;
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
vulkan13Features.dynamicRendering = vk::True;
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
vulkan13Features.pNext = &extendedDynamicStateFeatures;
features.pNext = &vulkan13Features;
vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT> featureChain = {
{}, // vk::PhysicalDeviceFeatures2
{.dynamicRendering = true }, // vk::PhysicalDeviceVulkan13Features
{.extendedDynamicState = true } // vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT
};

// create a Device
float queuePriority = 0.0f;
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{
.pNext = &features,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data()
};
vk::DeviceQueueCreateInfo deviceQueueCreateInfo{ .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &featureChain.get<vk::PhysicalDeviceFeatures2>(),
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &deviceQueueCreateInfo,
.enabledExtensionCount = static_cast<uint32_t>(requiredDeviceExtension.size()),
.ppEnabledExtensionNames = requiredDeviceExtension.data() };

device = vk::raii::Device( physicalDevice, deviceCreateInfo );
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
Expand Down
Loading
Loading