aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine.cpp171
1 files changed, 166 insertions, 5 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index 1d17ec2..0e29d60 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -14,6 +14,7 @@
#include <utility>
#include <numbers>
#include <optional>
+#include <algorithm>
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
@@ -292,10 +293,17 @@ static int main_term() {
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
-const std::vector<const char*> validation_layers = {
+static const std::vector<const char*> validation_layers = {
"VK_LAYER_KHRONOS_validation"
};
+static const std::vector<const char*> device_exts = {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ VK_KHR_SPIRV_1_4_EXTENSION_NAME,
+ VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
+ VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME,
+};
+
#ifdef NDEBUG
const bool enable_validation_layers = false;
#else
@@ -327,11 +335,12 @@ static bool check_validation_layer_support() {
return true;
}
+// TODO: remove [[maybe_unused]]
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
- VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
- VkDebugUtilsMessageTypeFlagsEXT message_type,
+ [[maybe_unused]] VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
+ [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT message_type,
const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
- void* user_data) {
+ [[maybe_unused]] void* user_data) {
std::cerr << "validation layer: " << callback_data->pMessage << std::endl;
return VK_FALSE;
}
@@ -369,7 +378,7 @@ static int main_graphical() {
app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.pEngineName = "engine";
app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
- app_info.apiVersion = VK_API_VERSION_1_0;
+ app_info.apiVersion = VK_API_VERSION_1_4;
std::vector<const char*> extensions;
@@ -437,6 +446,158 @@ static int main_graphical() {
create_debug_messenger(instance, &msger_create_info, nullptr, &debug_messenger);
}
+ // select physical device
+ uint32_t physical_devices_count;
+ vkEnumeratePhysicalDevices(instance, &physical_devices_count, nullptr);
+ std::vector<VkPhysicalDevice> physical_devices(physical_devices_count);
+ vkEnumeratePhysicalDevices(instance, &physical_devices_count, physical_devices.data());
+
+ if (physical_devices.empty()) {
+ std::cerr << "failed to find physical devices with Vulkan support" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ VkPhysicalDevice device;
+ bool found = false;
+ for (const auto& physical_device : physical_devices) {
+ VkPhysicalDeviceProperties2 properties{};
+ properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ vkGetPhysicalDeviceProperties2(physical_device, &properties);
+
+ VkPhysicalDeviceFeatures2 features{};
+ features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ vkGetPhysicalDeviceFeatures2(physical_device, &features);
+
+ uint32_t queue_family_properties_count;
+ vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_properties_count, nullptr);
+ std::vector<VkQueueFamilyProperties2> queue_family_properties(queue_family_properties_count);
+ vkGetPhysicalDeviceQueueFamilyProperties2(physical_device, &queue_family_properties_count, queue_family_properties.data());
+
+ // TODO: found a better name, too confusing with device_exts
+ uint32_t ext_props_count;
+ vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &ext_props_count, nullptr);
+ std::vector<VkExtensionProperties> ext_props(ext_props_count);
+ vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &ext_props_count, ext_props.data());
+
+ std::cout << "structure type: " << string_VkStructureType(properties.sType) << std::endl;
+ std::cout << "pNext: " << properties.pNext << std::endl;
+ std::cout << "apiVersion: (variant " << VK_API_VERSION_VARIANT(properties.properties.apiVersion) << ") "
+ << VK_API_VERSION_MAJOR(properties.properties.apiVersion)
+ << "." << VK_API_VERSION_MINOR(properties.properties.apiVersion)
+ << "." << VK_API_VERSION_PATCH(properties.properties.apiVersion)
+ << std::endl;
+ std::cout << "driverVersion: " << properties.properties.driverVersion << std::endl;
+ std::cout << "vendorID: " << properties.properties.vendorID << std::endl;
+ std::cout << "deviceID: " << properties.properties.deviceID << std::endl;
+ std::cout << "deviceType: " << string_VkPhysicalDeviceType(properties.properties.deviceType) << std::endl;
+ std::cout << "deviceName: " << properties.properties.deviceName << std::endl;
+ // pipelineCacheUUID[VK_UUID_SIZE]
+ // limits
+ std::cout << "sparseProperties:" << std::endl;
+ std::cout << std::boolalpha;
+ std::cout << " residencyStandard2DBlockShape: " << static_cast<bool>(properties.properties.sparseProperties.residencyStandard2DBlockShape) << std::endl;
+ std::cout << " residencyStandard2DMultisampleBlockShape: "
+ << static_cast<bool>(properties.properties.sparseProperties.residencyStandard2DMultisampleBlockShape) << std::endl;
+ std::cout << " residencyStandard3DBlockShape: " << static_cast<bool>(properties.properties.sparseProperties.residencyStandard3DBlockShape) << std::endl;
+ std::cout << " residencyAlignedMipSize: " << static_cast<bool>(properties.properties.sparseProperties.residencyAlignedMipSize) << std::endl;
+ std::cout << " residencyNonResidentStrict: " << static_cast<bool>(properties.properties.sparseProperties.residencyNonResidentStrict) << std::endl;
+ std::cout << std::noboolalpha;
+ std::cout << "features:" << std::endl;
+ std::cout << std::boolalpha;
+ std::cout << " robustBufferAccess: " << static_cast<bool>(features.features.robustBufferAccess) << std::endl;
+ std::cout << " fullDrawIndexUint32: " << static_cast<bool>(features.features.fullDrawIndexUint32) << std::endl;
+ std::cout << " imageCubeArray: " << static_cast<bool>(features.features.imageCubeArray) << std::endl;
+ std::cout << " independentBlend: " << static_cast<bool>(features.features.independentBlend) << std::endl;
+ std::cout << " geometryShader: " << static_cast<bool>(features.features.geometryShader) << std::endl;
+ std::cout << " tessellationShader: " << static_cast<bool>(features.features.tessellationShader) << std::endl;
+ std::cout << " sampleRateShading: " << static_cast<bool>(features.features.sampleRateShading) << std::endl;
+ std::cout << " dualSrcBlend: " << static_cast<bool>(features.features.dualSrcBlend) << std::endl;
+ std::cout << " logicOp: " << static_cast<bool>(features.features.logicOp) << std::endl;
+ std::cout << " multiDrawIndirect: " << static_cast<bool>(features.features.multiDrawIndirect) << std::endl;
+ std::cout << " drawIndirectFirstInstance: " << static_cast<bool>(features.features.drawIndirectFirstInstance) << std::endl;
+ std::cout << " depthClamp: " << static_cast<bool>(features.features.depthClamp) << std::endl;
+ std::cout << " depthBiasClamp: " << static_cast<bool>(features.features.depthBiasClamp) << std::endl;
+ std::cout << " fillModeNonSolid: " << static_cast<bool>(features.features.fillModeNonSolid) << std::endl;
+ std::cout << " depthBounds: " << static_cast<bool>(features.features.depthBounds) << std::endl;
+ std::cout << " wideLines: " << static_cast<bool>(features.features.wideLines) << std::endl;
+ std::cout << " largePoints: " << static_cast<bool>(features.features.largePoints) << std::endl;
+ std::cout << " alphaToOne: " << static_cast<bool>(features.features.alphaToOne) << std::endl;
+ std::cout << " multiViewport: " << static_cast<bool>(features.features.multiViewport) << std::endl;
+ std::cout << " samplerAnisotropy: " << static_cast<bool>(features.features.samplerAnisotropy) << std::endl;
+ std::cout << " textureCompressionETC2: " << static_cast<bool>(features.features.textureCompressionETC2) << std::endl;
+ std::cout << " textureCompressionASTC_LDR: " << static_cast<bool>(features.features.textureCompressionASTC_LDR) << std::endl;
+ std::cout << " textureCompressionBC: " << static_cast<bool>(features.features.textureCompressionBC) << std::endl;
+ std::cout << " occlusionQueryPrecise: " << static_cast<bool>(features.features.occlusionQueryPrecise) << std::endl;
+ std::cout << " pipelineStatisticsQuery: " << static_cast<bool>(features.features.pipelineStatisticsQuery) << std::endl;
+ std::cout << " vertexPipelineStoresAndAtomics: " << static_cast<bool>(features.features.vertexPipelineStoresAndAtomics) << std::endl;
+ std::cout << " fragmentStoresAndAtomics: " << static_cast<bool>(features.features.fragmentStoresAndAtomics) << std::endl;
+ std::cout << " shaderTessellationAndGeometryPointSize: " << static_cast<bool>(features.features.shaderTessellationAndGeometryPointSize) << std::endl;
+ std::cout << " shaderImageGatherExtended: " << static_cast<bool>(features.features.shaderImageGatherExtended) << std::endl;
+ std::cout << " shaderStorageImageExtendedFormats: " << static_cast<bool>(features.features.shaderStorageImageExtendedFormats) << std::endl;
+ std::cout << " shaderStorageImageMultisample: " << static_cast<bool>(features.features.shaderStorageImageMultisample) << std::endl;
+ std::cout << " shaderStorageImageReadWithoutFormat: " << static_cast<bool>(features.features.shaderStorageImageReadWithoutFormat) << std::endl;
+ std::cout << " shaderStorageImageWriteWithoutFormat: " << static_cast<bool>(features.features.shaderStorageImageWriteWithoutFormat) << std::endl;
+ std::cout << " shaderUniformBufferArrayDynamicIndexing: " << static_cast<bool>(features.features.shaderUniformBufferArrayDynamicIndexing) << std::endl;
+ std::cout << " shaderSampledImageArrayDynamicIndexing: " << static_cast<bool>(features.features.shaderSampledImageArrayDynamicIndexing) << std::endl;
+ std::cout << " shaderStorageBufferArrayDynamicIndexing: " << static_cast<bool>(features.features.shaderStorageBufferArrayDynamicIndexing) << std::endl;
+ std::cout << " shaderStorageImageArrayDynamicIndexing: " << static_cast<bool>(features.features.shaderStorageImageArrayDynamicIndexing) << std::endl;
+ std::cout << " shaderClipDistance: " << static_cast<bool>(features.features.shaderClipDistance) << std::endl;
+ std::cout << " shaderCullDistance: " << static_cast<bool>(features.features.shaderCullDistance) << std::endl;
+ std::cout << " shaderFloat64: " << static_cast<bool>(features.features.shaderFloat64) << std::endl;
+ std::cout << " shaderInt64: " << static_cast<bool>(features.features.shaderInt64) << std::endl;
+ std::cout << " shaderInt16: " << static_cast<bool>(features.features.shaderInt16) << std::endl;
+ std::cout << " shaderResourceResidency: " << static_cast<bool>(features.features.shaderResourceResidency) << std::endl;
+ std::cout << " shaderResourceMinLod: " << static_cast<bool>(features.features.shaderResourceMinLod) << std::endl;
+ std::cout << " sparseBinding: " << static_cast<bool>(features.features.sparseBinding) << std::endl;
+ std::cout << " sparseResidencyBuffer: " << static_cast<bool>(features.features.sparseResidencyBuffer) << std::endl;
+ std::cout << " sparseResidencyImage2D: " << static_cast<bool>(features.features.sparseResidencyImage2D) << std::endl;
+ std::cout << " sparseResidencyImage3D: " << static_cast<bool>(features.features.sparseResidencyImage3D) << std::endl;
+ std::cout << " sparseResidency2Samples: " << static_cast<bool>(features.features.sparseResidency2Samples) << std::endl;
+ std::cout << " sparseResidency4Samples: " << static_cast<bool>(features.features.sparseResidency4Samples) << std::endl;
+ std::cout << " sparseResidency8Samples: " << static_cast<bool>(features.features.sparseResidency8Samples) << std::endl;
+ std::cout << " sparseResidency16Samples: " << static_cast<bool>(features.features.sparseResidency16Samples) << std::endl;
+ std::cout << " sparseResidencyAliased: " << static_cast<bool>(features.features.sparseResidencyAliased) << std::endl;
+ std::cout << " variableMultisampleRate: " << static_cast<bool>(features.features.variableMultisampleRate) << std::endl;
+ std::cout << " inheritedQueries: " << static_cast<bool>(features.features.inheritedQueries) << std::endl;
+ std::cout << std::noboolalpha;
+ std::cout << "extensions:" << std::endl;
+ for (const auto& ext : ext_props) {
+ std::cout
+ << (std::ranges::find_if(device_exts, [ext_name=ext.extensionName](const auto& device_ext) { return strcmp(ext_name, device_ext) == 0; })
+ != device_exts.end() ? "*" : " ");
+ std::cout << " " << ext.extensionName << std::endl;
+ }
+
+ bool is_suitable = [&properties, &queue_family_properties, &ext_props]() {
+ if (VK_API_VERSION_VARIANT(properties.properties.apiVersion) != 0
+ || properties.properties.apiVersion < VK_API_VERSION_1_4)
+ return false;
+ if (std::ranges::find_if(queue_family_properties, [](const auto& prop) {
+ return (prop.queueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT) != static_cast<VkQueueFlags>(0);
+ }) == queue_family_properties.end())
+ return false;
+ if (std::ranges::find_if_not(device_exts, [&ext_props](const auto& device_ext) {
+ return std::ranges::find_if(ext_props,
+ [device_ext](const auto& ext_prop) { return strcmp(ext_prop.extensionName, device_ext) == 0; })
+ != ext_props.end();
+ }) != device_exts.end())
+ return false;
+ return true;
+ }();
+ std::cout << "is_suitable: " << std::boolalpha << is_suitable << std::noboolalpha;
+ if (!found && is_suitable) {
+ found = true;
+ std::cout << " (picking this one)";
+ device = physical_device;
+ }
+ std::cout << std::endl;
+ }
+
+ if (!found) {
+ std::cerr << "no suitable physical device found" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
// main loop
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();