Compare commits

..

No commits in common. "6ed76af2100247cb14aaa5b5c14fda619d605d18" and "020993fb19b326adb692ff2aa2635936078f82a7" have entirely different histories.

View file

@ -203,230 +203,212 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VK_EXTENSIONS.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); VK_EXTENSIONS.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
#endif // VULKAN_VALIDATION == 1 #endif // VULKAN_VALIDATION == 1
VkInstance instance; VkApplicationInfo app_info{};
utility::Cleanup cleanup_vk_instance{}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
VkDebugUtilsMessengerEXT debug_messenger; app_info.pApplicationName = "Blue Noise Generation";
utility::Cleanup cleanup_debug_messenger{}; app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
{ app_info.pEngineName = "No Engine";
VkApplicationInfo app_info{}; app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.apiVersion = VK_API_VERSION_1_0;
app_info.pApplicationName = "Blue Noise Generation";
app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.pEngineName = "No Engine";
app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.apiVersion = VK_API_VERSION_1_0;
VkInstanceCreateInfo create_info{}; VkInstanceCreateInfo create_info{};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
create_info.pApplicationInfo = &app_info; create_info.pApplicationInfo = &app_info;
create_info.enabledExtensionCount = VK_EXTENSIONS.size(); create_info.enabledExtensionCount = VK_EXTENSIONS.size();
create_info.ppEnabledExtensionNames = VK_EXTENSIONS.data(); create_info.ppEnabledExtensionNames = VK_EXTENSIONS.data();
VkDebugUtilsMessengerCreateInfoEXT debug_create_info{}; VkDebugUtilsMessengerCreateInfoEXT debug_create_info{};
#if VULKAN_VALIDATION == 1 #if VULKAN_VALIDATION == 1
create_info.enabledLayerCount = VALIDATION_LAYERS.size(); create_info.enabledLayerCount = VALIDATION_LAYERS.size();
create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data(); create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data();
const auto populate_debug_info = const auto populate_debug_info =
[](VkDebugUtilsMessengerCreateInfoEXT *info) { [](VkDebugUtilsMessengerCreateInfoEXT *info) {
info->sType = info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; info->messageSeverity =
info->messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; info->pfnUserCallback = fn_VULKAN_DEBUG_CALLBACK;
info->pfnUserCallback = fn_VULKAN_DEBUG_CALLBACK; };
};
populate_debug_info(&debug_create_info); populate_debug_info(&debug_create_info);
create_info.pNext = &debug_create_info; create_info.pNext = &debug_create_info;
#else #else
create_info.enabledLayerCount = 0; create_info.enabledLayerCount = 0;
create_info.pNext = nullptr; create_info.pNext = nullptr;
#endif // VULKAN_VALIDATION == 1 #endif // VULKAN_VALIDATION == 1
if (vkCreateInstance(&create_info, nullptr, &instance) != VK_SUCCESS) {
std::clog << "WARNING: Failed to create Vulkan instance!\n"; VkInstance instance;
goto ENDOF_VULKAN; if (vkCreateInstance(&create_info, nullptr, &instance) != VK_SUCCESS) {
} std::clog << "WARNING: Failed to create Vulkan instance!\n";
cleanup_vk_instance = utility::Cleanup( goto ENDOF_VULKAN;
[](void *ptr) { vkDestroyInstance(*((VkInstance *)ptr), nullptr); }, }
&instance); utility::Cleanup cleanup_vk_instance(
[](void *ptr) { vkDestroyInstance(*((VkInstance *)ptr), nullptr); },
&instance);
#if VULKAN_VALIDATION == 1 #if VULKAN_VALIDATION == 1
populate_debug_info(&debug_create_info); populate_debug_info(&debug_create_info);
VkDebugUtilsMessengerEXT debug_messenger;
auto create_debug_utils_messenger_func = auto create_debug_utils_messenger_func =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
instance, "vkCreateDebugUtilsMessengerEXT"); instance, "vkCreateDebugUtilsMessengerEXT");
if (create_debug_utils_messenger_func != nullptr && if (create_debug_utils_messenger_func != nullptr &&
create_debug_utils_messenger_func(instance, &debug_create_info, create_debug_utils_messenger_func(instance, &debug_create_info, nullptr,
nullptr, &debug_messenger) != VK_SUCCESS) {
&debug_messenger) != VK_SUCCESS) { std::clog << "WARNING: Failed to set up Vulkan debug messenger!\n";
std::clog << "WARNING: Failed to set up Vulkan debug messenger!\n"; goto ENDOF_VULKAN;
goto ENDOF_VULKAN; }
} utility::Cleanup cleanup_debug_messenger(
cleanup_debug_messenger = utility::Cleanup( [instance](void *ptr) {
[instance](void *ptr) { auto func =
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr( instance, "vkDestroyDebugUtilsMessengerEXT");
instance, "vkDestroyDebugUtilsMessengerEXT"); if (func != nullptr) {
if (func != nullptr) { func(instance, *((VkDebugUtilsMessengerEXT *)ptr), nullptr);
func(instance, *((VkDebugUtilsMessengerEXT *)ptr), nullptr); }
} },
}, &debug_messenger);
&debug_messenger);
#endif // VULKAN_VALIDATION == 1 #endif // VULKAN_VALIDATION == 1
uint32_t device_count = 0;
vkEnumeratePhysicalDevices(instance, &device_count, nullptr);
if (device_count == 0) {
std::clog << "WARNING: No GPUs available with Vulkan support!\n";
goto ENDOF_VULKAN;
}
std::vector<VkPhysicalDevice> devices(device_count);
vkEnumeratePhysicalDevices(instance, &device_count, devices.data());
std::optional<VkPhysicalDevice> gpu_dev_discrete;
std::optional<VkPhysicalDevice> gpu_dev_integrated;
for (const auto &device : devices) {
auto indices = find_queue_families(device);
VkPhysicalDeviceProperties dev_props{};
vkGetPhysicalDeviceProperties(device, &dev_props);
if (indices.isComplete()) {
if (dev_props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
gpu_dev_discrete = device;
} else if (dev_props.deviceType ==
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
gpu_dev_integrated = device;
}
}
} }
VkPhysicalDevice phys_device; VkPhysicalDevice phys_device;
{ if (gpu_dev_discrete.has_value()) {
uint32_t device_count = 0; std::clog << "NOTICE: Found discrete GPU supporting Vulkan compute.\n";
vkEnumeratePhysicalDevices(instance, &device_count, nullptr); phys_device = gpu_dev_discrete.value();
if (device_count == 0) { } else if (gpu_dev_integrated.has_value()) {
std::clog << "WARNING: No GPUs available with Vulkan support!\n"; std::clog << "NOTICE: Found integrated GPU supporting Vulkan compute.\n";
goto ENDOF_VULKAN; phys_device = gpu_dev_integrated.value();
} } else {
std::vector<VkPhysicalDevice> devices(device_count); std::clog << "WARNING: No suitable GPUs found!\n";
vkEnumeratePhysicalDevices(instance, &device_count, devices.data()); goto ENDOF_VULKAN;
std::optional<VkPhysicalDevice> gpu_dev_discrete;
std::optional<VkPhysicalDevice> gpu_dev_integrated;
for (const auto &device : devices) {
auto indices = find_queue_families(device);
VkPhysicalDeviceProperties dev_props{};
vkGetPhysicalDeviceProperties(device, &dev_props);
if (indices.isComplete()) {
if (dev_props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
gpu_dev_discrete = device;
} else if (dev_props.deviceType ==
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
gpu_dev_integrated = 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";
phys_device = gpu_dev_integrated.value();
} else {
std::clog << "WARNING: No suitable GPUs found!\n";
goto ENDOF_VULKAN;
}
} }
VkDevice device; auto indices = find_queue_families(phys_device);
utility::Cleanup device_cleanup{}; std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
{ std::unordered_set<uint32_t> unique_queue_families = {
auto indices = find_queue_families(phys_device); indices.computeFamily.value()};
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
std::unordered_set<uint32_t> unique_queue_families = {
indices.computeFamily.value()};
float queue_priority = 1.0F; float queue_priority = 1.0F;
for (uint32_t queue_family : unique_queue_families) { for (uint32_t queue_family : unique_queue_families) {
VkDeviceQueueCreateInfo queue_create_info{}; VkDeviceQueueCreateInfo queue_create_info{};
queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_info.queueFamilyIndex = queue_family; queue_create_info.queueFamilyIndex = queue_family;
queue_create_info.queueCount = 1; queue_create_info.queueCount = 1;
queue_create_info.pQueuePriorities = &queue_priority; queue_create_info.pQueuePriorities = &queue_priority;
queue_create_infos.push_back(queue_create_info); queue_create_infos.push_back(queue_create_info);
} }
VkPhysicalDeviceFeatures device_features{}; VkPhysicalDeviceFeatures device_features{};
VkDeviceCreateInfo dev_create_info{}; VkDeviceCreateInfo dev_create_info{};
dev_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; dev_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
dev_create_info.queueCreateInfoCount = queue_create_infos.size(); dev_create_info.queueCreateInfoCount = queue_create_infos.size();
dev_create_info.pQueueCreateInfos = queue_create_infos.data(); dev_create_info.pQueueCreateInfos = queue_create_infos.data();
dev_create_info.pEnabledFeatures = &device_features; dev_create_info.pEnabledFeatures = &device_features;
dev_create_info.enabledExtensionCount = 0; dev_create_info.enabledExtensionCount = 0;
#if VULKAN_VALIDATION == 1 #if VULKAN_VALIDATION == 1
dev_create_info.enabledLayerCount = VALIDATION_LAYERS.size(); dev_create_info.enabledLayerCount = VALIDATION_LAYERS.size();
dev_create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data(); dev_create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data();
#else #else
dev_create_info.enabledLayerCount = 0; dev_create_info.enabledLayerCount = 0;
#endif #endif
if (vkCreateDevice(phys_device, &dev_create_info, nullptr, &device) != VkDevice device;
VK_SUCCESS) { if (vkCreateDevice(phys_device, &dev_create_info, nullptr, &device) !=
std::clog << "WARNING: Failed to create VkDevice!\n"; VK_SUCCESS) {
goto ENDOF_VULKAN; std::clog << "WARNING: Failed to create VkDevice!\n";
} goto ENDOF_VULKAN;
device_cleanup = utility::Cleanup(
[](void *ptr) { vkDestroyDevice(*((VkDevice *)ptr), nullptr); },
&device);
} }
utility::Cleanup device_cleanup(
[](void *ptr) { vkDestroyDevice(*((VkDevice *)ptr), nullptr); },
&device);
VkQueue compute_queue; VkQueue compute_queue;
vkGetDeviceQueue(device, vkGetDeviceQueue(device, indices.computeFamily.value(), 0, &compute_queue);
find_queue_families(phys_device).computeFamily.value(), 0,
&compute_queue); std::array<VkDescriptorSetLayoutBinding, 4> compute_layout_bindings{};
compute_layout_bindings[0].binding = 0;
compute_layout_bindings[0].descriptorCount = 1;
compute_layout_bindings[0].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[0].pImmutableSamplers = nullptr;
compute_layout_bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[1].binding = 1;
compute_layout_bindings[1].descriptorCount = 1;
compute_layout_bindings[1].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[1].pImmutableSamplers = nullptr;
compute_layout_bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[2].binding = 2;
compute_layout_bindings[2].descriptorCount = 1;
compute_layout_bindings[2].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[2].pImmutableSamplers = nullptr;
compute_layout_bindings[2].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[3].binding = 3;
compute_layout_bindings[3].descriptorCount = 1;
compute_layout_bindings[3].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[3].pImmutableSamplers = nullptr;
compute_layout_bindings[3].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
VkDescriptorSetLayoutCreateInfo layout_info{};
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layout_info.bindingCount = compute_layout_bindings.size();
layout_info.pBindings = compute_layout_bindings.data();
VkDescriptorSetLayout compute_desc_set_layout; VkDescriptorSetLayout compute_desc_set_layout;
utility::Cleanup compute_desc_set_layout_cleanup{}; if (vkCreateDescriptorSetLayout(device, &layout_info, nullptr,
{ &compute_desc_set_layout) != VK_SUCCESS) {
std::array<VkDescriptorSetLayoutBinding, 4> compute_layout_bindings{}; std::clog << "WARNING: Failed to create compute descriptor set layout!\n";
compute_layout_bindings[0].binding = 0; goto ENDOF_VULKAN;
compute_layout_bindings[0].descriptorCount = 1;
compute_layout_bindings[0].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[0].pImmutableSamplers = nullptr;
compute_layout_bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[1].binding = 1;
compute_layout_bindings[1].descriptorCount = 1;
compute_layout_bindings[1].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[1].pImmutableSamplers = nullptr;
compute_layout_bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[2].binding = 2;
compute_layout_bindings[2].descriptorCount = 1;
compute_layout_bindings[2].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[2].pImmutableSamplers = nullptr;
compute_layout_bindings[2].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
compute_layout_bindings[3].binding = 3;
compute_layout_bindings[3].descriptorCount = 1;
compute_layout_bindings[3].descriptorType =
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
compute_layout_bindings[3].pImmutableSamplers = nullptr;
compute_layout_bindings[3].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
VkDescriptorSetLayoutCreateInfo layout_info{};
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layout_info.bindingCount = compute_layout_bindings.size();
layout_info.pBindings = compute_layout_bindings.data();
if (vkCreateDescriptorSetLayout(device, &layout_info, nullptr,
&compute_desc_set_layout) != VK_SUCCESS) {
std::clog
<< "WARNING: Failed to create compute descriptor set layout!\n";
goto ENDOF_VULKAN;
}
compute_desc_set_layout_cleanup = utility::Cleanup(
[device](void *ptr) {
vkDestroyDescriptorSetLayout(
device, *((VkDescriptorSetLayout *)ptr), nullptr);
},
&compute_desc_set_layout);
} }
utility::Cleanup compute_desc_set_layout_cleanup(
[device](void *ptr) {
vkDestroyDescriptorSetLayout(device, *((VkDescriptorSetLayout *)ptr),
nullptr);
},
&compute_desc_set_layout);
// Check and compile compute shader. // Check and compile compute shader.
{ {
@ -544,8 +526,7 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkCommandPoolCreateInfo pool_info{}; VkCommandPoolCreateInfo pool_info{};
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
pool_info.queueFamilyIndex = pool_info.queueFamilyIndex = indices.computeFamily.value();
find_queue_families(phys_device).computeFamily.value();
if (vkCreateCommandPool(device, &pool_info, nullptr, &command_pool) != if (vkCreateCommandPool(device, &pool_info, nullptr, &command_pool) !=
VK_SUCCESS) { VK_SUCCESS) {