Skip to content

Commit 3121659

Browse files
committed
Address all comments. Still working on compute_shader.cpp
Refactor device extension handling and physical device selection logic Unified device extension references to `requiredDeviceExtension` for clarity and consistency. Improved physical device selection by incorporating checks for Vulkan 1.3 features and necessary dynamic rendering capabilities. Enhanced code readability with structured initialization and modern Vulkan C++ practices.
1 parent 6e8e382 commit 3121659

26 files changed

+1307
-1051
lines changed

attachments/03_physical_device_selection.cpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class HelloTriangleApplication {
4343

4444
vk::raii::PhysicalDevice physicalDevice = nullptr;
4545

46-
std::vector<const char*> deviceExtensions = {
46+
std::vector<const char*> requiredDeviceExtension = {
4747
vk::KHRSwapchainExtensionName,
4848
vk::KHRSpirv14ExtensionName,
4949
vk::KHRSynchronization2ExtensionName,
@@ -116,31 +116,42 @@ class HelloTriangleApplication {
116116

117117
void pickPhysicalDevice() {
118118
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
119-
const auto devIter = std::ranges::find_if(devices,
120-
[&](auto const & device) {
121-
auto queueFamilies = device.getQueueFamilyProperties();
122-
bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
123-
const auto qfpIter = std::ranges::find_if(queueFamilies,
124-
[]( vk::QueueFamilyProperties const & qfp )
125-
{
126-
return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
127-
} );
128-
isSuitable = isSuitable && ( qfpIter != queueFamilies.end() );
129-
auto extensions = device.enumerateDeviceExtensionProperties( );
130-
bool found = true;
131-
for (auto const & extension : deviceExtensions) {
132-
auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;});
133-
found = found && extensionIter != extensions.end();
134-
}
135-
isSuitable = isSuitable && found;
136-
printf("\n");
137-
if (isSuitable) {
138-
physicalDevice = device;
139-
}
140-
return isSuitable;
141-
});
142-
if (devIter == devices.end()) {
143-
throw std::runtime_error("failed to find a suitable GPU!");
119+
const auto devIter = std::ranges::find_if(
120+
devices,
121+
[&]( auto const & device )
122+
{
123+
// Check if the device supports the Vulkan 1.3 API version
124+
bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
125+
126+
// Check if any of the queue families support graphics operations
127+
auto queueFamilies = device.getQueueFamilyProperties();
128+
bool supportsGraphics =
129+
std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } );
130+
131+
// Check if all required device extensions are available
132+
auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties();
133+
bool supportsAllRequiredExtensions =
134+
std::ranges::all_of( requiredDeviceExtension,
135+
[&availableDeviceExtensions]( auto const & requiredDeviceExtension )
136+
{
137+
return std::ranges::any_of( availableDeviceExtensions,
138+
[requiredDeviceExtension]( auto const & availableDeviceExtension )
139+
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
140+
} );
141+
142+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
143+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
144+
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
145+
146+
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
147+
} );
148+
if ( devIter != devices.end() )
149+
{
150+
physicalDevice = *devIter;
151+
}
152+
else
153+
{
154+
throw std::runtime_error( "failed to find a suitable GPU!" );
144155
}
145156
}
146157

attachments/04_logical_device.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class HelloTriangleApplication {
4646

4747
vk::raii::Queue graphicsQueue = nullptr;
4848

49-
std::vector<const char*> deviceExtensions = {
49+
std::vector<const char*> requiredDeviceExtension = {
5050
vk::KHRSwapchainExtensionName,
5151
vk::KHRSpirv14ExtensionName,
5252
vk::KHRSynchronization2ExtensionName,
@@ -120,31 +120,42 @@ class HelloTriangleApplication {
120120

121121
void pickPhysicalDevice() {
122122
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
123-
const auto devIter = std::ranges::find_if(devices,
124-
[&](auto const & device) {
125-
auto queueFamilies = device.getQueueFamilyProperties();
126-
bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
127-
const auto qfpIter = std::ranges::find_if(queueFamilies,
128-
[]( vk::QueueFamilyProperties const & qfp )
129-
{
130-
return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
131-
} );
132-
isSuitable = isSuitable && ( qfpIter != queueFamilies.end() );
133-
auto extensions = device.enumerateDeviceExtensionProperties( );
134-
bool found = true;
135-
for (auto const & extension : deviceExtensions) {
136-
auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;});
137-
found = found && extensionIter != extensions.end();
138-
}
139-
isSuitable = isSuitable && found;
140-
printf("\n");
141-
if (isSuitable) {
142-
physicalDevice = device;
143-
}
144-
return isSuitable;
145-
});
146-
if (devIter == devices.end()) {
147-
throw std::runtime_error("failed to find a suitable GPU!");
123+
const auto devIter = std::ranges::find_if(
124+
devices,
125+
[&]( auto const & device )
126+
{
127+
// Check if the device supports the Vulkan 1.3 API version
128+
bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
129+
130+
// Check if any of the queue families support graphics operations
131+
auto queueFamilies = device.getQueueFamilyProperties();
132+
bool supportsGraphics =
133+
std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } );
134+
135+
// Check if all required device extensions are available
136+
auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties();
137+
bool supportsAllRequiredExtensions =
138+
std::ranges::all_of( requiredDeviceExtension,
139+
[&availableDeviceExtensions]( auto const & requiredDeviceExtension )
140+
{
141+
return std::ranges::any_of( availableDeviceExtensions,
142+
[requiredDeviceExtension]( auto const & availableDeviceExtension )
143+
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
144+
} );
145+
146+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
147+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
148+
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
149+
150+
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
151+
} );
152+
if ( devIter != devices.end() )
153+
{
154+
physicalDevice = *devIter;
155+
}
156+
else
157+
{
158+
throw std::runtime_error( "failed to find a suitable GPU!" );
148159
}
149160
}
150161

@@ -170,8 +181,8 @@ class HelloTriangleApplication {
170181
float queuePriority = 0.0f;
171182
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
172183
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
173-
deviceCreateInfo.enabledExtensionCount = deviceExtensions.size();
174-
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
184+
deviceCreateInfo.enabledExtensionCount = requiredDeviceExtension.size();
185+
deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtension.data();
175186

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

attachments/05_window_surface.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class HelloTriangleApplication {
4848
vk::raii::Queue graphicsQueue = nullptr;
4949
vk::raii::Queue presentQueue = nullptr;
5050

51-
std::vector<const char*> deviceExtensions = {
51+
std::vector<const char*> requiredDeviceExtension = {
5252
vk::KHRSwapchainExtensionName,
5353
vk::KHRSpirv14ExtensionName,
5454
vk::KHRSynchronization2ExtensionName,
@@ -131,31 +131,42 @@ class HelloTriangleApplication {
131131

132132
void pickPhysicalDevice() {
133133
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
134-
const auto devIter = std::ranges::find_if(devices,
135-
[&](auto const & device) {
136-
auto queueFamilies = device.getQueueFamilyProperties();
137-
bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
138-
const auto qfpIter = std::ranges::find_if(queueFamilies,
139-
[]( vk::QueueFamilyProperties const & qfp )
140-
{
141-
return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
142-
} );
143-
isSuitable = isSuitable && ( qfpIter != queueFamilies.end() );
144-
auto extensions = device.enumerateDeviceExtensionProperties( );
145-
bool found = true;
146-
for (auto const & extension : deviceExtensions) {
147-
auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;});
148-
found = found && extensionIter != extensions.end();
149-
}
150-
isSuitable = isSuitable && found;
151-
printf("\n");
152-
if (isSuitable) {
153-
physicalDevice = device;
154-
}
155-
return isSuitable;
156-
});
157-
if (devIter == devices.end()) {
158-
throw std::runtime_error("failed to find a suitable GPU!");
134+
const auto devIter = std::ranges::find_if(
135+
devices,
136+
[&]( auto const & device )
137+
{
138+
// Check if the device supports the Vulkan 1.3 API version
139+
bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
140+
141+
// Check if any of the queue families support graphics operations
142+
auto queueFamilies = device.getQueueFamilyProperties();
143+
bool supportsGraphics =
144+
std::ranges::any_of( queueFamilies, []( auto const & qfp ) { return !!( qfp.queueFlags & vk::QueueFlagBits::eGraphics ); } );
145+
146+
// Check if all required device extensions are available
147+
auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties();
148+
bool supportsAllRequiredExtensions =
149+
std::ranges::all_of( requiredDeviceExtension,
150+
[&availableDeviceExtensions]( auto const & requiredDeviceExtension )
151+
{
152+
return std::ranges::any_of( availableDeviceExtensions,
153+
[requiredDeviceExtension]( auto const & availableDeviceExtension )
154+
{ return strcmp( availableDeviceExtension.extensionName, requiredDeviceExtension ) == 0; } );
155+
} );
156+
157+
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
158+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
159+
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
160+
161+
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
162+
} );
163+
if ( devIter != devices.end() )
164+
{
165+
physicalDevice = *devIter;
166+
}
167+
else
168+
{
169+
throw std::runtime_error( "failed to find a suitable GPU!" );
159170
}
160171
}
161172

@@ -219,8 +230,8 @@ class HelloTriangleApplication {
219230
float queuePriority = 0.0f;
220231
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
221232
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
222-
deviceCreateInfo.enabledExtensionCount = deviceExtensions.size();
223-
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
233+
deviceCreateInfo.enabledExtensionCount = requiredDeviceExtension.size();
234+
deviceCreateInfo.ppEnabledExtensionNames = requiredDeviceExtension.data();
224235

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

0 commit comments

Comments
 (0)