Skip to content

Commit d0b8c94

Browse files
authored
Merge branch 'main' into main
2 parents 4aba80a + 6ae0280 commit d0b8c94

187 files changed

Lines changed: 6034 additions & 5898 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ attachments/simple_engine/android/app/build/**
3030
attachments/simple_engine/android/gradle/wrapper/**
3131
attachments/simple_engine/android/gradlew
3232
attachments/simple_engine/android/gradlew.bat
33+
34+
attachments/template/build/**

attachments/02_validation_layers.cpp

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,36 +92,38 @@ class HelloTriangleApplication
9292
}
9393

9494
// Check if the required layers are supported by the Vulkan implementation.
95-
auto layerProperties = context.enumerateInstanceLayerProperties();
96-
for (auto const &requiredLayer : requiredLayers)
95+
auto layerProperties = context.enumerateInstanceLayerProperties();
96+
auto unsupportedLayerIt = std::ranges::find_if(requiredLayers,
97+
[&layerProperties](auto const &requiredLayer) {
98+
return std::ranges::none_of(layerProperties,
99+
[requiredLayer](auto const &layerProperty) { return strcmp(layerProperty.layerName, requiredLayer) == 0; });
100+
});
101+
if (unsupportedLayerIt != requiredLayers.end())
97102
{
98-
if (std::ranges::none_of(layerProperties,
99-
[requiredLayer](auto const &layerProperty) { return strcmp(layerProperty.layerName, requiredLayer) == 0; }))
100-
{
101-
throw std::runtime_error("Required layer not supported: " + std::string(requiredLayer));
102-
}
103+
throw std::runtime_error("Required layer not supported: " + std::string(*unsupportedLayerIt));
103104
}
104105

105106
// Get the required extensions.
106-
auto requiredExtensions = getRequiredExtensions();
107+
auto requiredExtensions = getRequiredInstanceExtensions();
107108

108109
// Check if the required extensions are supported by the Vulkan implementation.
109110
auto extensionProperties = context.enumerateInstanceExtensionProperties();
110-
for (auto const &requiredExtension : requiredExtensions)
111+
auto unsupportedPropertyIt =
112+
std::ranges::find_if(requiredExtensions,
113+
[&extensionProperties](auto const &requiredExtension) {
114+
return std::ranges::none_of(extensionProperties,
115+
[requiredExtension](auto const &extensionProperty) { return strcmp(extensionProperty.extensionName, requiredExtension) == 0; });
116+
});
117+
if (unsupportedPropertyIt != requiredExtensions.end())
111118
{
112-
if (std::ranges::none_of(extensionProperties,
113-
[requiredExtension](auto const &extensionProperty) { return strcmp(extensionProperty.extensionName, requiredExtension) == 0; }))
114-
{
115-
throw std::runtime_error("Required extension not supported: " + std::string(requiredExtension));
116-
}
119+
throw std::runtime_error("Required extension not supported: " + std::string(*unsupportedPropertyIt));
117120
}
118121

119-
vk::InstanceCreateInfo createInfo{
120-
.pApplicationInfo = &appInfo,
121-
.enabledLayerCount = static_cast<uint32_t>(requiredLayers.size()),
122-
.ppEnabledLayerNames = requiredLayers.data(),
123-
.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()),
124-
.ppEnabledExtensionNames = requiredExtensions.data()};
122+
vk::InstanceCreateInfo createInfo{.pApplicationInfo = &appInfo,
123+
.enabledLayerCount = static_cast<uint32_t>(requiredLayers.size()),
124+
.ppEnabledLayerNames = requiredLayers.data(),
125+
.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()),
126+
.ppEnabledExtensionNames = requiredExtensions.data()};
125127
instance = vk::raii::Instance(context, createInfo);
126128
}
127129

@@ -130,16 +132,17 @@ class HelloTriangleApplication
130132
if (!enableValidationLayers)
131133
return;
132134

133-
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError);
134-
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation);
135-
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
136-
.messageSeverity = severityFlags,
137-
.messageType = messageTypeFlags,
138-
.pfnUserCallback = &debugCallback};
135+
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
136+
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError);
137+
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(
138+
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation);
139+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{.messageSeverity = severityFlags,
140+
.messageType = messageTypeFlags,
141+
.pfnUserCallback = &debugCallback};
139142
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
140143
}
141144

142-
std::vector<const char *> getRequiredExtensions()
145+
std::vector<const char *> getRequiredInstanceExtensions()
143146
{
144147
uint32_t glfwExtensionCount = 0;
145148
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

attachments/03_physical_device_selection.cpp

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -98,36 +98,38 @@ class HelloTriangleApplication
9898
}
9999

100100
// Check if the required layers are supported by the Vulkan implementation.
101-
auto layerProperties = context.enumerateInstanceLayerProperties();
102-
for (auto const &requiredLayer : requiredLayers)
101+
auto layerProperties = context.enumerateInstanceLayerProperties();
102+
auto unsupportedLayerIt = std::ranges::find_if(requiredLayers,
103+
[&layerProperties](auto const &requiredLayer) {
104+
return std::ranges::none_of(layerProperties,
105+
[requiredLayer](auto const &layerProperty) { return strcmp(layerProperty.layerName, requiredLayer) == 0; });
106+
});
107+
if (unsupportedLayerIt != requiredLayers.end())
103108
{
104-
if (std::ranges::none_of(layerProperties,
105-
[requiredLayer](auto const &layerProperty) { return strcmp(layerProperty.layerName, requiredLayer) == 0; }))
106-
{
107-
throw std::runtime_error("Required layer not supported: " + std::string(requiredLayer));
108-
}
109+
throw std::runtime_error("Required layer not supported: " + std::string(*unsupportedLayerIt));
109110
}
110111

111112
// Get the required extensions.
112-
auto requiredExtensions = getRequiredExtensions();
113+
auto requiredExtensions = getRequiredInstanceExtensions();
113114

114115
// Check if the required extensions are supported by the Vulkan implementation.
115116
auto extensionProperties = context.enumerateInstanceExtensionProperties();
116-
for (auto const &requiredExtension : requiredExtensions)
117+
auto unsupportedPropertyIt =
118+
std::ranges::find_if(requiredExtensions,
119+
[&extensionProperties](auto const &requiredExtension) {
120+
return std::ranges::none_of(extensionProperties,
121+
[requiredExtension](auto const &extensionProperty) { return strcmp(extensionProperty.extensionName, requiredExtension) == 0; });
122+
});
123+
if (unsupportedPropertyIt != requiredExtensions.end())
117124
{
118-
if (std::ranges::none_of(extensionProperties,
119-
[requiredExtension](auto const &extensionProperty) { return strcmp(extensionProperty.extensionName, requiredExtension) == 0; }))
120-
{
121-
throw std::runtime_error("Required extension not supported: " + std::string(requiredExtension));
122-
}
125+
throw std::runtime_error("Required extension not supported: " + std::string(*unsupportedPropertyIt));
123126
}
124127

125-
vk::InstanceCreateInfo createInfo{
126-
.pApplicationInfo = &appInfo,
127-
.enabledLayerCount = static_cast<uint32_t>(requiredLayers.size()),
128-
.ppEnabledLayerNames = requiredLayers.data(),
129-
.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()),
130-
.ppEnabledExtensionNames = requiredExtensions.data()};
128+
vk::InstanceCreateInfo createInfo{.pApplicationInfo = &appInfo,
129+
.enabledLayerCount = static_cast<uint32_t>(requiredLayers.size()),
130+
.ppEnabledLayerNames = requiredLayers.data(),
131+
.enabledExtensionCount = static_cast<uint32_t>(requiredExtensions.size()),
132+
.ppEnabledExtensionNames = requiredExtensions.data()};
131133
instance = vk::raii::Instance(context, createInfo);
132134
}
133135

@@ -136,55 +138,59 @@ class HelloTriangleApplication
136138
if (!enableValidationLayers)
137139
return;
138140

139-
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError);
140-
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation);
141-
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
142-
.messageSeverity = severityFlags,
143-
.messageType = messageTypeFlags,
144-
.pfnUserCallback = &debugCallback};
141+
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags(vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
142+
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError);
143+
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags(
144+
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation);
145+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{.messageSeverity = severityFlags,
146+
.messageType = messageTypeFlags,
147+
.pfnUserCallback = &debugCallback};
145148
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
146149
}
147150

151+
bool isDeviceSuitable(vk::raii::PhysicalDevice const &physicalDevice)
152+
{
153+
// Check if the physicalDevice supports the Vulkan 1.3 API version
154+
bool supportsVulkan1_3 = physicalDevice.getProperties().apiVersion >= vk::ApiVersion13;
155+
156+
// Check if any of the queue families support graphics operations
157+
auto queueFamilies = physicalDevice.getQueueFamilyProperties();
158+
bool supportsGraphics = std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); });
159+
160+
// Check if all required physicalDevice extensions are available
161+
auto availableDeviceExtensions = physicalDevice.enumerateDeviceExtensionProperties();
162+
bool supportsAllRequiredExtensions =
163+
std::ranges::all_of(requiredDeviceExtension,
164+
[&availableDeviceExtensions](auto const &requiredDeviceExtension) {
165+
return std::ranges::any_of(availableDeviceExtensions,
166+
[requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; });
167+
});
168+
169+
// Check if the physicalDevice supports the required features
170+
auto features = physicalDevice.template getFeatures2<vk::PhysicalDeviceFeatures2,
171+
vk::PhysicalDeviceVulkan11Features,
172+
vk::PhysicalDeviceVulkan13Features,
173+
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
174+
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan11Features>().shaderDrawParameters &&
175+
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
176+
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
177+
178+
// Return true if the physicalDevice meets all the criteria
179+
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
180+
}
181+
148182
void pickPhysicalDevice()
149183
{
150-
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
151-
const auto devIter = std::ranges::find_if(
152-
devices,
153-
[&](auto const &device) {
154-
// Check if the device supports the Vulkan 1.3 API version
155-
bool supportsVulkan1_3 = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
156-
157-
// Check if any of the queue families support graphics operations
158-
auto queueFamilies = device.getQueueFamilyProperties();
159-
bool supportsGraphics =
160-
std::ranges::any_of(queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); });
161-
162-
// Check if all required device extensions are available
163-
auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties();
164-
bool supportsAllRequiredExtensions =
165-
std::ranges::all_of(requiredDeviceExtension,
166-
[&availableDeviceExtensions](auto const &requiredDeviceExtension) {
167-
return std::ranges::any_of(availableDeviceExtensions,
168-
[requiredDeviceExtension](auto const &availableDeviceExtension) { return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; });
169-
});
170-
171-
auto features = device.template getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features, vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
172-
bool supportsRequiredFeatures = features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
173-
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().extendedDynamicState;
174-
175-
return supportsVulkan1_3 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures;
176-
});
177-
if (devIter != devices.end())
178-
{
179-
physicalDevice = *devIter;
180-
}
181-
else
184+
std::vector<vk::raii::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
185+
auto const devIter = std::ranges::find_if(physicalDevices, [&](auto const &physicalDevice) { return isDeviceSuitable(physicalDevice); });
186+
if (devIter == physicalDevices.end())
182187
{
183188
throw std::runtime_error("failed to find a suitable GPU!");
184189
}
190+
physicalDevice = *devIter;
185191
}
186192

187-
std::vector<const char *> getRequiredExtensions()
193+
std::vector<const char *> getRequiredInstanceExtensions()
188194
{
189195
uint32_t glfwExtensionCount = 0;
190196
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

0 commit comments

Comments
 (0)