Compare commits

...

2 commits

Author SHA1 Message Date
6ed76af210 Restructure vulkan init code
Vulkan init code was resturctured so that "temporary" structs (e.g.
vulkan "info create" structs) are discarded after they are used.
2024-03-21 12:07:46 +09:00
3b11564a4a Addendum note to previous commit
It was assumed in the previous commit's message that the shader data was
stored on the stack. In actuality, the usage of std::vector<char> uses
dynamically allocated memory, which means the data should be on the heap
not the stack.
2024-03-21 11:56:12 +09:00

View file

@ -203,6 +203,11 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VK_EXTENSIONS.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
#endif // VULKAN_VALIDATION == 1
VkInstance instance;
utility::Cleanup cleanup_vk_instance{};
VkDebugUtilsMessengerEXT debug_messenger;
utility::Cleanup cleanup_debug_messenger{};
{
VkApplicationInfo app_info{};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pApplicationName = "Blue Noise Generation";
@ -225,7 +230,8 @@ image::Bl dither::blue_noise(int width, int height, int threads,
const auto populate_debug_info =
[](VkDebugUtilsMessengerCreateInfoEXT *info) {
info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
info->sType =
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
info->messageSeverity =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
@ -243,30 +249,28 @@ image::Bl dither::blue_noise(int width, int height, int threads,
create_info.enabledLayerCount = 0;
create_info.pNext = nullptr;
#endif // VULKAN_VALIDATION == 1
VkInstance instance;
if (vkCreateInstance(&create_info, nullptr, &instance) != VK_SUCCESS) {
std::clog << "WARNING: Failed to create Vulkan instance!\n";
goto ENDOF_VULKAN;
}
utility::Cleanup cleanup_vk_instance(
cleanup_vk_instance = utility::Cleanup(
[](void *ptr) { vkDestroyInstance(*((VkInstance *)ptr), nullptr); },
&instance);
#if VULKAN_VALIDATION == 1
populate_debug_info(&debug_create_info);
VkDebugUtilsMessengerEXT debug_messenger;
auto create_debug_utils_messenger_func =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
instance, "vkCreateDebugUtilsMessengerEXT");
if (create_debug_utils_messenger_func != nullptr &&
create_debug_utils_messenger_func(instance, &debug_create_info, nullptr,
create_debug_utils_messenger_func(instance, &debug_create_info,
nullptr,
&debug_messenger) != VK_SUCCESS) {
std::clog << "WARNING: Failed to set up Vulkan debug messenger!\n";
goto ENDOF_VULKAN;
}
utility::Cleanup cleanup_debug_messenger(
cleanup_debug_messenger = utility::Cleanup(
[instance](void *ptr) {
auto func =
(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
@ -277,6 +281,10 @@ image::Bl dither::blue_noise(int width, int height, int threads,
},
&debug_messenger);
#endif // VULKAN_VALIDATION == 1
}
VkPhysicalDevice phys_device;
{
uint32_t device_count = 0;
vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
if (device_count == 0) {
@ -304,18 +312,22 @@ image::Bl dither::blue_noise(int width, int height, int threads,
}
}
VkPhysicalDevice phys_device;
if (gpu_dev_discrete.has_value()) {
std::clog << "NOTICE: Found discrete GPU supporting Vulkan compute.\n";
phys_device = gpu_dev_discrete.value();
} else if (gpu_dev_integrated.has_value()) {
std::clog << "NOTICE: Found integrated GPU supporting Vulkan compute.\n";
std::clog
<< "NOTICE: Found integrated GPU supporting Vulkan compute.\n";
phys_device = gpu_dev_integrated.value();
} else {
std::clog << "WARNING: No suitable GPUs found!\n";
goto ENDOF_VULKAN;
}
}
VkDevice device;
utility::Cleanup device_cleanup{};
{
auto indices = find_queue_families(phys_device);
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
std::unordered_set<uint32_t> unique_queue_families = {
@ -350,19 +362,24 @@ image::Bl dither::blue_noise(int width, int height, int threads,
dev_create_info.enabledLayerCount = 0;
#endif
VkDevice device;
if (vkCreateDevice(phys_device, &dev_create_info, nullptr, &device) !=
VK_SUCCESS) {
std::clog << "WARNING: Failed to create VkDevice!\n";
goto ENDOF_VULKAN;
}
utility::Cleanup device_cleanup(
device_cleanup = utility::Cleanup(
[](void *ptr) { vkDestroyDevice(*((VkDevice *)ptr), nullptr); },
&device);
}
VkQueue compute_queue;
vkGetDeviceQueue(device, indices.computeFamily.value(), 0, &compute_queue);
vkGetDeviceQueue(device,
find_queue_families(phys_device).computeFamily.value(), 0,
&compute_queue);
VkDescriptorSetLayout compute_desc_set_layout;
utility::Cleanup compute_desc_set_layout_cleanup{};
{
std::array<VkDescriptorSetLayoutBinding, 4> compute_layout_bindings{};
compute_layout_bindings[0].binding = 0;
compute_layout_bindings[0].descriptorCount = 1;
@ -397,18 +414,19 @@ image::Bl dither::blue_noise(int width, int height, int threads,
layout_info.bindingCount = compute_layout_bindings.size();
layout_info.pBindings = compute_layout_bindings.data();
VkDescriptorSetLayout compute_desc_set_layout;
if (vkCreateDescriptorSetLayout(device, &layout_info, nullptr,
&compute_desc_set_layout) != VK_SUCCESS) {
std::clog << "WARNING: Failed to create compute descriptor set layout!\n";
std::clog
<< "WARNING: Failed to create compute descriptor set layout!\n";
goto ENDOF_VULKAN;
}
utility::Cleanup compute_desc_set_layout_cleanup(
compute_desc_set_layout_cleanup = utility::Cleanup(
[device](void *ptr) {
vkDestroyDescriptorSetLayout(device, *((VkDescriptorSetLayout *)ptr),
nullptr);
vkDestroyDescriptorSetLayout(
device, *((VkDescriptorSetLayout *)ptr), nullptr);
},
&compute_desc_set_layout);
}
// Check and compile compute shader.
{
@ -526,7 +544,8 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkCommandPoolCreateInfo pool_info{};
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
pool_info.queueFamilyIndex = indices.computeFamily.value();
pool_info.queueFamilyIndex =
find_queue_families(phys_device).computeFamily.value();
if (vkCreateCommandPool(device, &pool_info, nullptr, &command_pool) !=
VK_SUCCESS) {