Define vulkan specific helper fns in header

This commit is contained in:
Stephen Seo 2024-03-22 16:59:23 +09:00
parent 03b3c90e9a
commit 16f0e0e865
2 changed files with 86 additions and 60 deletions

View file

@ -17,7 +17,6 @@
#endif #endif
#if DITHERING_VULKAN_ENABLED == 1 #if DITHERING_VULKAN_ENABLED == 1
#include <vulkan/vulkan.h>
static std::vector<const char *> VK_EXTENSIONS = {}; static std::vector<const char *> VK_EXTENSIONS = {};
@ -34,15 +33,8 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL fn_VULKAN_DEBUG_CALLBACK(
} }
#endif // VULKAN_VALIDATION == 1 #endif // VULKAN_VALIDATION == 1
struct QueueFamilyIndices { dither::internal::QueueFamilyIndices
QueueFamilyIndices() : computeFamily() {} dither::internal::vulkan_find_queue_families(VkPhysicalDevice device) {
std::optional<uint32_t> computeFamily;
bool isComplete() { return computeFamily.has_value(); }
};
QueueFamilyIndices find_queue_families(VkPhysicalDevice device) {
QueueFamilyIndices indices; QueueFamilyIndices indices;
uint32_t queue_family_count = 0; uint32_t queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count,
@ -64,9 +56,8 @@ QueueFamilyIndices find_queue_families(VkPhysicalDevice device) {
return indices; return indices;
} }
std::optional<uint32_t> vulkan_find_memory_type(VkPhysicalDevice phys_dev, std::optional<uint32_t> dither::internal::vulkan_find_memory_type(
uint32_t t_filter, VkPhysicalDevice phys_dev, uint32_t t_filter, VkMemoryPropertyFlags props) {
VkMemoryPropertyFlags props) {
VkPhysicalDeviceMemoryProperties mem_props; VkPhysicalDeviceMemoryProperties mem_props;
vkGetPhysicalDeviceMemoryProperties(phys_dev, &mem_props); vkGetPhysicalDeviceMemoryProperties(phys_dev, &mem_props);
@ -80,10 +71,10 @@ std::optional<uint32_t> vulkan_find_memory_type(VkPhysicalDevice phys_dev,
return std::nullopt; return std::nullopt;
} }
bool vulkan_create_buffer(VkDevice device, VkPhysicalDevice phys_dev, bool dither::internal::vulkan_create_buffer(
VkDeviceSize size, VkBufferUsageFlags usage, VkDevice device, VkPhysicalDevice phys_dev, VkDeviceSize size,
VkMemoryPropertyFlags props, VkBuffer &buf, VkBufferUsageFlags usage, VkMemoryPropertyFlags props, VkBuffer &buf,
VkDeviceMemory &buf_mem) { VkDeviceMemory &buf_mem) {
VkBufferCreateInfo buf_info{}; VkBufferCreateInfo buf_info{};
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buf_info.size = size; buf_info.size = size;
@ -124,9 +115,10 @@ bool vulkan_create_buffer(VkDevice device, VkPhysicalDevice phys_dev,
return true; return true;
} }
void vulkan_copy_buffer(VkDevice device, VkCommandPool command_pool, void dither::internal::vulkan_copy_buffer(VkDevice device,
VkQueue queue, VkBuffer src_buf, VkBuffer dst_buf, VkCommandPool command_pool,
VkDeviceSize size) { VkQueue queue, VkBuffer src_buf,
VkBuffer dst_buf, VkDeviceSize size) {
VkCommandBufferAllocateInfo alloc_info{}; VkCommandBufferAllocateInfo alloc_info{};
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
@ -297,7 +289,7 @@ image::Bl dither::blue_noise(int width, int height, int threads,
std::optional<VkPhysicalDevice> gpu_dev_discrete; std::optional<VkPhysicalDevice> gpu_dev_discrete;
std::optional<VkPhysicalDevice> gpu_dev_integrated; std::optional<VkPhysicalDevice> gpu_dev_integrated;
for (const auto &device : devices) { for (const auto &device : devices) {
auto indices = find_queue_families(device); auto indices = internal::vulkan_find_queue_families(device);
VkPhysicalDeviceProperties dev_props{}; VkPhysicalDeviceProperties dev_props{};
vkGetPhysicalDeviceProperties(device, &dev_props); vkGetPhysicalDeviceProperties(device, &dev_props);
@ -328,7 +320,7 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkDevice device; VkDevice device;
utility::Cleanup device_cleanup{}; utility::Cleanup device_cleanup{};
{ {
auto indices = find_queue_families(phys_device); auto indices = internal::vulkan_find_queue_families(phys_device);
std::vector<VkDeviceQueueCreateInfo> queue_create_infos; std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
std::unordered_set<uint32_t> unique_queue_families = { std::unordered_set<uint32_t> unique_queue_families = {
indices.computeFamily.value()}; indices.computeFamily.value()};
@ -373,9 +365,10 @@ image::Bl dither::blue_noise(int width, int height, int threads,
} }
VkQueue compute_queue; VkQueue compute_queue;
vkGetDeviceQueue(device, vkGetDeviceQueue(
find_queue_families(phys_device).computeFamily.value(), 0, device,
&compute_queue); internal::vulkan_find_queue_families(phys_device).computeFamily.value(),
0, &compute_queue);
VkDescriptorSetLayout compute_desc_set_layout; VkDescriptorSetLayout compute_desc_set_layout;
utility::Cleanup compute_desc_set_layout_cleanup{}; utility::Cleanup compute_desc_set_layout_cleanup{};
@ -545,7 +538,8 @@ image::Bl dither::blue_noise(int width, int height, int threads,
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 =
find_queue_families(phys_device).computeFamily.value(); internal::vulkan_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) {
@ -574,11 +568,12 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkBuffer staging_buffer; VkBuffer staging_buffer;
VkDeviceMemory staging_buffer_mem; VkDeviceMemory staging_buffer_mem;
if (!vulkan_create_buffer(device, phys_device, precomputed_size, if (!internal::vulkan_create_buffer(
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, device, phys_device, precomputed_size,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
staging_buffer, staging_buffer_mem)) { VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging_buffer, staging_buffer_mem)) {
std::clog << "WARNING: Failed to create staging buffer!\n"; std::clog << "WARNING: Failed to create staging buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -599,11 +594,12 @@ image::Bl dither::blue_noise(int width, int height, int threads,
std::memcpy(data_ptr, precomputed.data(), precomputed_size); std::memcpy(data_ptr, precomputed.data(), precomputed_size);
vkUnmapMemory(device, staging_buffer_mem); vkUnmapMemory(device, staging_buffer_mem);
if (!vulkan_create_buffer(device, phys_device, precomputed_size, if (!internal::vulkan_create_buffer(device, phys_device, precomputed_size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
precomputed_buf, precomputed_buf_mem)) { precomputed_buf,
precomputed_buf_mem)) {
std::clog << "WARNING: Failed to create precomputed buffer!\n"; std::clog << "WARNING: Failed to create precomputed buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -618,17 +614,18 @@ image::Bl dither::blue_noise(int width, int height, int threads,
}, },
&precomputed_buf_mem); &precomputed_buf_mem);
vulkan_copy_buffer(device, command_pool, compute_queue, staging_buffer, internal::vulkan_copy_buffer(device, command_pool, compute_queue,
precomputed_buf, precomputed_size); staging_buffer, precomputed_buf,
precomputed_size);
} }
VkBuffer filter_out_buf; VkBuffer filter_out_buf;
VkDeviceMemory filter_out_buf_mem; VkDeviceMemory filter_out_buf_mem;
if (!vulkan_create_buffer(device, phys_device, filter_out_size, if (!internal::vulkan_create_buffer(device, phys_device, filter_out_size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
filter_out_buf, filter_out_buf_mem)) { filter_out_buf, filter_out_buf_mem)) {
std::clog << "WARNING: Failed to create filter_out buffer!\n"; std::clog << "WARNING: Failed to create filter_out buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -645,11 +642,11 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkBuffer pbp_buf; VkBuffer pbp_buf;
VkDeviceMemory pbp_buf_mem; VkDeviceMemory pbp_buf_mem;
if (!vulkan_create_buffer(device, phys_device, pbp_size, if (!internal::vulkan_create_buffer(device, phys_device, pbp_size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, pbp_buf, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
pbp_buf_mem)) { pbp_buf, pbp_buf_mem)) {
std::clog << "WARNING: Failed to create pbp buffer!\n"; std::clog << "WARNING: Failed to create pbp buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -672,11 +669,11 @@ image::Bl dither::blue_noise(int width, int height, int threads,
VkBuffer staging_buffer; VkBuffer staging_buffer;
VkDeviceMemory staging_buffer_mem; VkDeviceMemory staging_buffer_mem;
if (!vulkan_create_buffer(device, phys_device, other_size, if (!internal::vulkan_create_buffer(
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, device, phys_device, other_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging_buffer, staging_buffer_mem)) { staging_buffer, staging_buffer_mem)) {
std::clog << "WARNING: Failed to create staging buffer!\n"; std::clog << "WARNING: Failed to create staging buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -705,11 +702,11 @@ image::Bl dither::blue_noise(int width, int height, int threads,
} }
vkUnmapMemory(device, staging_buffer_mem); vkUnmapMemory(device, staging_buffer_mem);
if (!vulkan_create_buffer(device, phys_device, other_size, if (!internal::vulkan_create_buffer(device, phys_device, other_size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, other_buf, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
other_buf_mem)) { other_buf, other_buf_mem)) {
std::clog << "WARNING: Failed to create other buffer!\n"; std::clog << "WARNING: Failed to create other buffer!\n";
goto ENDOF_VULKAN; goto ENDOF_VULKAN;
} }
@ -724,8 +721,8 @@ image::Bl dither::blue_noise(int width, int height, int threads,
}, },
&other_buf_mem); &other_buf_mem);
vulkan_copy_buffer(device, command_pool, compute_queue, staging_buffer, internal::vulkan_copy_buffer(device, command_pool, compute_queue,
other_buf, other_size); staging_buffer, other_buf, other_size);
} }
} }
ENDOF_VULKAN: ENDOF_VULKAN:

View file

@ -4,6 +4,9 @@
#if DITHERING_OPENCL_ENABLED == 1 #if DITHERING_OPENCL_ENABLED == 1
#include <CL/opencl.h> #include <CL/opencl.h>
#endif #endif
#if DITHERING_VULKAN_ENABLED == 1
#include <vulkan/vulkan.h>
#endif
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <cassert> #include <cassert>
@ -33,6 +36,32 @@ image::Bl blue_noise(int width, int height, int threads = 1,
namespace internal { namespace internal {
std::vector<unsigned int> blue_noise_impl(int width, int height, std::vector<unsigned int> blue_noise_impl(int width, int height,
int threads = 1); int threads = 1);
#if DITHERING_VULKAN_ENABLED == 1
struct QueueFamilyIndices {
QueueFamilyIndices() : computeFamily() {}
std::optional<uint32_t> computeFamily;
bool isComplete() { return computeFamily.has_value(); }
};
QueueFamilyIndices vulkan_find_queue_families(VkPhysicalDevice device);
std::optional<uint32_t> vulkan_find_memory_type(VkPhysicalDevice phys_dev,
uint32_t t_filter,
VkMemoryPropertyFlags props);
bool vulkan_create_buffer(VkDevice device, VkPhysicalDevice phys_dev,
VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags props, VkBuffer &buf,
VkDeviceMemory &buf_mem);
void vulkan_copy_buffer(VkDevice device, VkCommandPool command_pool,
VkQueue queue, VkBuffer src_buf, VkBuffer dst_buf,
VkDeviceSize size);
#endif
#if DITHERING_OPENCL_ENABLED == 1 #if DITHERING_OPENCL_ENABLED == 1
std::vector<unsigned int> blue_noise_cl_impl(const int width, const int height, std::vector<unsigned int> blue_noise_cl_impl(const int width, const int height,
const int filter_size, const int filter_size,