aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2025-12-20 23:32:33 +0100
committervimene <vincent.menegaux@gmail.com>2025-12-20 23:32:33 +0100
commitc3409e800b80fa383eff37ef5382b6661dadb976 (patch)
tree3c41005fcaf7593bc8e870aef706550b5ca0bc2f
parent09411b34a4b2c3a235a5621110543744484d2a15 (diff)
downloadengine-c3409e800b80fa383eff37ef5382b6661dadb976.tar.gz
still more code refactoring
-rw-r--r--src/engine.cpp182
1 files changed, 85 insertions, 97 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index aa9c644..0cf829a 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -303,7 +303,7 @@ static const std::vector<const char*> validation_layers = {
"VK_LAYER_KHRONOS_validation",
};
-static const std::vector<const char*> device_exts = {
+static const std::vector<const char*> physical_device_ext_names = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_SPIRV_1_4_EXTENSION_NAME,
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
@@ -325,30 +325,24 @@ struct PhysicalDeviceEntry {
};
static bool check_validation_layer_support() {
- uint32_t layer_count;
- if (VkResult res = vkEnumerateInstanceLayerProperties(&layer_count, nullptr); res != VK_SUCCESS) {
- std::cerr << "failed to enumerate instance layer properties, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
- std::vector<VkLayerProperties> available_layers(layer_count);
- if (VkResult res = vkEnumerateInstanceLayerProperties(&layer_count, available_layers.data()); res != VK_SUCCESS) {
- std::cerr << "failed to enumerate instance layer properties, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
-
- for (const char* layer_name : validation_layers) {
- bool layer_found = false;
-
- for (const auto& layer_properties : available_layers) {
- if (strcmp(layer_name, layer_properties.layerName) == 0) {
- layer_found = true;
- break;
- }
+ auto avail_layers = [&]() {
+ uint32_t avail_layers_count;
+ if (VkResult res = vkEnumerateInstanceLayerProperties(&avail_layers_count, nullptr); res != VK_SUCCESS) {
+ std::cerr << "failed to enumerate instance layer properties, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::vector<VkLayerProperties> avail_layers(avail_layers_count);
+ if (VkResult res = vkEnumerateInstanceLayerProperties(&avail_layers_count, avail_layers.data()); res != VK_SUCCESS) {
+ std::cerr << "failed to enumerate instance layer properties, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
}
+ return avail_layers;
+ }();
- if (!layer_found) {
+ for (const char* layer_name : validation_layers) {
+ if (std::ranges::find_if(avail_layers, [&](const auto& props) { return strcmp(layer_name, props.layerName) == 0; })
+ == avail_layers.end())
return false;
- }
}
return true;
@@ -356,25 +350,19 @@ static bool check_validation_layer_support() {
static std::string severity_to_str(VkDebugUtilsMessageSeverityFlagBitsEXT severity) {
switch (severity) {
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
- return "VERBOSE";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
- return "INFO";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
- return "WARNING";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
- return "ERROR";
- default:
- std::unreachable();
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: return "VERBOSE";
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: return "INFO";
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: return "WARNING";
+ case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: return "ERROR";
+ default: std::unreachable();
}
}
-// TODO: remove [[maybe_unused]]
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
- [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT message_type,
+ VkDebugUtilsMessageTypeFlagsEXT /* message_type */,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
- [[maybe_unused]] void* user_data) {
+ void* /* user_data */) {
std::cerr << "validation layer: [" << severity_to_str(message_severity) << "] " << callback_data->pMessage << std::endl;
return VK_FALSE;
}
@@ -593,9 +581,6 @@ static int main_graphical() {
for (uint32_t i = 0; i < avail_physical_devices.size(); i++) {
const auto& avail_physical_device = avail_physical_devices[i];
- PhysicalDeviceEntry physical_device_entry;
- physical_device_entry.physical_device = avail_physical_device;
-
auto physical_device_props = [&]() {
VkPhysicalDeviceProperties2 physical_device_props{};
physical_device_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
@@ -606,7 +591,7 @@ static int main_graphical() {
std::cout << " " << (i + 1) << ". " << physical_device_props.properties.deviceName << ":" << std::endl;
std::cout << " apiVersion: " << engine::myvk::api { physical_device_props.properties.apiVersion } << std::endl;
- physical_device_entry.features = [&]() {
+ auto physical_device_features = [&]() {
VkPhysicalDeviceFeatures2 physical_device_features{};
physical_device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
vkGetPhysicalDeviceFeatures2(avail_physical_device, &physical_device_features);
@@ -630,7 +615,7 @@ static int main_graphical() {
}();
std::cout << " required physical device extensions:" << std::endl;
- for (const auto& ext : device_exts) {
+ for (const auto& ext : physical_device_ext_names) {
std::cout << " " << (std::ranges::find_if(physical_device_ext_props, [&](const auto& avail_ext) {
return strcmp(avail_ext.extensionName, ext) == 0;
}) == physical_device_ext_props.end() ? "!" : " ");
@@ -667,47 +652,47 @@ static int main_graphical() {
return std::optional<unsigned> {};
if (!graphics_queue_family_index || !present_queue_family_index)
return std::optional<unsigned> {};
- if (std::ranges::find_if_not(device_exts, [&](const auto& device_ext) {
+ if (std::ranges::find_if_not(physical_device_ext_names, [&](const auto& device_ext) {
return std::ranges::find_if(physical_device_ext_props,
[&](const auto& ext_prop) { return strcmp(ext_prop.extensionName, device_ext) == 0; })
!= physical_device_ext_props.end();
- }) != device_exts.end())
+ }) != physical_device_ext_names.end())
return std::optional<unsigned> {};
unsigned score = 0;
if (*graphics_queue_family_index == *present_queue_family_index)
score += 5;
- switch (physical_device_props.properties.deviceType) {
- case VK_PHYSICAL_DEVICE_TYPE_OTHER:
- score += 0;
- break;
- case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
- score += 2;
- break;
- case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
- score += 10;
- break;
- case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
- score += 5;
- break;
- case VK_PHYSICAL_DEVICE_TYPE_CPU:
- score += 1;
- break;
- default:
- // TODO: make it better, because if in the future vulkan add more device types,
- // it can crash
- std::unreachable();
- }
+
+ score += [&](VkPhysicalDeviceType device_type) {
+ switch (device_type) {
+ case VK_PHYSICAL_DEVICE_TYPE_OTHER: return 0;
+ case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: return 2;
+ case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: return 10;
+ case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: return 5;
+ case VK_PHYSICAL_DEVICE_TYPE_CPU: return 1;
+ default:
+ {
+ std::cerr << "device type not supported: " << string_VkPhysicalDeviceType(device_type) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ }
+ }(physical_device_props.properties.deviceType);
+
return std::optional<unsigned> { score };
}();
std::cout << " is suitable: " << std::boolalpha << static_cast<bool>(score) << std::noboolalpha << std::endl;
- if (score) {
- physical_device_entry.graphics_queue_family_index = *graphics_queue_family_index;
- physical_device_entry.present_queue_family_index = *present_queue_family_index;
- physical_device_entry.name = physical_device_props.properties.deviceName;
- physical_devices.insert({ *score, physical_device_entry });
- }
+ if (score)
+ physical_devices.insert({ *score,
+ {
+ .idx = i,
+ .physical_device = avail_physical_device,
+ .name = physical_device_props.properties.deviceName,
+ .graphics_queue_family_index = *graphics_queue_family_index,
+ .present_queue_family_index = *present_queue_family_index,
+ .features = physical_device_features,
+ }
+ });
}
std::cout << std::endl;
@@ -787,8 +772,8 @@ static int main_graphical() {
.pQueueCreateInfos = device_queue_cis.data(),
.enabledLayerCount = {},
.ppEnabledLayerNames = {},
- .enabledExtensionCount = static_cast<uint32_t>(device_exts.size()),
- .ppEnabledExtensionNames = device_exts.data(),
+ .enabledExtensionCount = static_cast<uint32_t>(physical_device_ext_names.size()),
+ .ppEnabledExtensionNames = physical_device_ext_names.data(),
.pEnabledFeatures = {},
};
@@ -836,16 +821,19 @@ static int main_graphical() {
}();
auto surface_format = [&]() {
- uint32_t surface_formats_count;
- if (VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &surface_formats_count, nullptr); res != VK_SUCCESS) {
- std::cerr << "failed to get physical device surface formats, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
- std::vector<VkSurfaceFormatKHR> surface_formats(surface_formats_count);
- if (VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &surface_formats_count, surface_formats.data()); res != VK_SUCCESS) {
- std::cerr << "failed to get physical device surface formats, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
+ auto surface_formats = [&]() {
+ uint32_t surface_formats_count;
+ if (VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &surface_formats_count, nullptr); res != VK_SUCCESS) {
+ std::cerr << "failed to get physical device surface formats, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::vector<VkSurfaceFormatKHR> surface_formats(surface_formats_count);
+ if (VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &surface_formats_count, surface_formats.data()); res != VK_SUCCESS) {
+ std::cerr << "failed to get physical device surface formats, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ return surface_formats;
+ }();
for (const auto& surface_format : surface_formats) {
if (surface_format.format == VK_FORMAT_B8G8R8A8_SRGB
@@ -968,19 +956,19 @@ static int main_graphical() {
auto [pl_layout, graphics_pl] = [&]() {
// reading shader file
auto shader_module = [&]() {
- // shader code has to be 32-bits aligned, which is the case with the default allocator
- std::vector<char> shader_code;
- {
+ auto shader_code = [&]() {
const char* shader_file_name = SHADERSDIR "/shader.spv";
std::ifstream shader_file(shader_file_name, std::ios::ate | std::ios::binary);
if (!shader_file.is_open()) {
- std::cerr << "file `" << shader_file_name << "'not found" << std::endl; // TODO: improve
+ std::cerr << "file `" << shader_file_name << "' not found" << std::endl; // TODO: improve
std::exit(EXIT_SUCCESS);
}
- shader_code.resize(shader_file.tellg());
+ // shader code has to be 32-bits aligned, which is the case with the default allocator
+ std::vector<char> shader_code(shader_file.tellg());
shader_file.seekg(0, std::ios::beg);
shader_file.read(shader_code.data(), static_cast<std::streamsize>(shader_code.size()));
- }
+ return shader_code;
+ }();
VkShaderModuleCreateInfo shader_module_ci {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
@@ -998,7 +986,7 @@ static int main_graphical() {
}();
auto [pl_layout, graphics_pl] = [&]() {
- std::array pl_shader_stage_create_infos {
+ std::array pl_shader_stage_cis {
VkPipelineShaderStageCreateInfo {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
@@ -1146,8 +1134,8 @@ static int main_graphical() {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = &pl_render_ci,
.flags = {},
- .stageCount = 2,
- .pStages = pl_shader_stage_create_infos.data(),
+ .stageCount = static_cast<uint32_t>(pl_shader_stage_cis.size()),
+ .pStages = pl_shader_stage_cis.data(),
.pVertexInputState = &pl_vert_in_state_ci,
.pInputAssemblyState = &pl_in_asm_state_ci,
.pTessellationState = {},
@@ -1250,6 +1238,11 @@ static int main_graphical() {
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
+ if (VkResult res = vkWaitForFences(device, 1, &fence_draw, VK_TRUE, std::numeric_limits<uint64_t>::max()); res != VK_SUCCESS) {
+ std::cerr << "failed to wait for draw fence, error code: " << string_VkResult(res) << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
if (VkResult res = vkQueueWaitIdle(present_queue); res != VK_SUCCESS) {
std::cerr << "failed to wait idle for graphics queue, error code: " << string_VkResult(res) << std::endl;
std::exit(EXIT_FAILURE);
@@ -1373,11 +1366,6 @@ static int main_graphical() {
}
}
- if (VkResult res = vkWaitForFences(device, 1, &fence_draw, VK_TRUE, std::numeric_limits<uint64_t>::max()); res != VK_SUCCESS) {
- std::cerr << "failed to wait for draw fence, error code: " << string_VkResult(res) << std::endl;
- std::exit(EXIT_FAILURE);
- }
-
{
VkPresentInfoKHR present_info {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
@@ -1408,8 +1396,8 @@ static int main_graphical() {
vkDestroyCommandPool(device, cmd_pool, nullptr);
vkDestroyPipeline(device, graphics_pl, nullptr);
vkDestroyPipelineLayout(device, pl_layout, nullptr);
- for (const auto img_view : swapchain_img_views)
- vkDestroyImageView(device, img_view, nullptr);
+ for (auto it_img_view = swapchain_img_views.rbegin(); it_img_view != swapchain_img_views.rend(); ++it_img_view)
+ vkDestroyImageView(device, *it_img_view, nullptr);
vkDestroySwapchainKHR(device, swapchain, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
vkDestroyDevice(device, nullptr);