diff --git a/src/blue_noise.cpp b/src/blue_noise.cpp index 015c6f6..1cf5ba1 100644 --- a/src/blue_noise.cpp +++ b/src/blue_noise.cpp @@ -186,11 +186,11 @@ void dither::internal::vulkan_invalidate_buffer(VkDevice device, } std::vector dither::internal::blue_noise_vulkan_impl( - VkDevice device, VkPhysicalDevice phys_device, - VkCommandBuffer command_buffer, VkCommandPool command_pool, VkQueue queue, - VkBuffer pbp_buf, VkPipeline pipeline, VkPipelineLayout pipeline_layout, - VkDescriptorSet descriptor_set, VkBuffer filter_out_buf, const int width, - const int height) { + VkDevice device, VkCommandBuffer command_buffer, VkQueue queue, + VkPipeline pipeline, VkPipelineLayout pipeline_layout, + VkDescriptorSet descriptor_set, float *filter_out_mapped, int *pbp_mapped, + VkDeviceMemory filter_out_buf_mem, VkDeviceMemory pbp_buf_mem, + const int width, const int height) { const int size = width * height; const int pixel_count = size * 4 / 10; const int local_size = 256; @@ -200,85 +200,21 @@ std::vector dither::internal::blue_noise_vulkan_impl( std::vector pbp = random_noise(size, pixel_count); bool reversed_pbp = false; - VkBuffer staging_pbp_buffer; - VkDeviceMemory staging_pbp_buffer_mem; - void *pbp_mapped; - if (!internal::vulkan_create_buffer(device, phys_device, size * sizeof(int), - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - staging_pbp_buffer, - staging_pbp_buffer_mem)) { - std::clog << "get_filter ERROR: Failed to create staging pbp buffer!\n"; - return {}; - } - utility::Cleanup cleanup_staging_pbp_buf( - [device](void *ptr) { - vkDestroyBuffer(device, *((VkBuffer *)ptr), nullptr); - }, - &staging_pbp_buffer); - utility::Cleanup cleanup_staging_pbp_buf_mem( - [device](void *ptr) { - vkFreeMemory(device, *((VkDeviceMemory *)ptr), nullptr); - }, - &staging_pbp_buffer_mem); - vkMapMemory(device, staging_pbp_buffer_mem, 0, size * sizeof(int), 0, - &pbp_mapped); - utility::Cleanup cleanup_pbp_mapped( - [device](void *ptr) { vkUnmapMemory(device, *((VkDeviceMemory *)ptr)); }, - &staging_pbp_buffer_mem); - int *pbp_mapped_int = (int *)pbp_mapped; - - VkBuffer staging_filter_buffer; - VkDeviceMemory staging_filter_buffer_mem; - void *filter_mapped; - if (!internal::vulkan_create_buffer(device, phys_device, size * sizeof(int), - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - staging_filter_buffer, - staging_filter_buffer_mem)) { - std::clog << "get_filter ERROR: Failed to create staging pbp buffer!\n"; - return {}; - } - utility::Cleanup cleanup_staging_filter_buf( - [device](void *ptr) { - vkDestroyBuffer(device, *((VkBuffer *)ptr), nullptr); - }, - &staging_filter_buffer); - utility::Cleanup cleanup_staging_filter_buf_mem( - [device](void *ptr) { - vkFreeMemory(device, *((VkDeviceMemory *)ptr), nullptr); - }, - &staging_filter_buffer_mem); - vkMapMemory(device, staging_filter_buffer_mem, 0, size * sizeof(float), 0, - &filter_mapped); - utility::Cleanup cleanup_filter_mapped( - [device](void *ptr) { vkUnmapMemory(device, *((VkDeviceMemory *)ptr)); }, - &staging_filter_buffer_mem); - float *filter_mapped_float = (float *)filter_mapped; - - const auto get_filter = [device, command_buffer, command_pool, queue, pbp_buf, - pipeline, pipeline_layout, descriptor_set, - filter_out_buf, size, &pbp, &reversed_pbp, - global_size, pbp_mapped_int, staging_pbp_buffer, - staging_pbp_buffer_mem, staging_filter_buffer_mem, - staging_filter_buffer]() -> bool { + const auto get_filter = [device, command_buffer, queue, pipeline, + pipeline_layout, descriptor_set, &pbp, &reversed_pbp, + global_size, filter_out_buf_mem, pbp_buf_mem, + pbp_mapped]() -> bool { vkResetCommandBuffer(command_buffer, 0); for (unsigned int i = 0; i < pbp.size(); ++i) { if (reversed_pbp) { - pbp_mapped_int[i] = pbp[i] ? 0 : 1; + pbp_mapped[i] = pbp[i] ? 0 : 1; } else { - pbp_mapped_int[i] = pbp[i] ? 1 : 0; + pbp_mapped[i] = pbp[i] ? 1 : 0; } } - vulkan_flush_buffer(device, staging_pbp_buffer_mem); - - // Copy pbp buffer. - vulkan_copy_buffer(device, command_pool, queue, staging_pbp_buffer, pbp_buf, - size * sizeof(int)); + vulkan_flush_buffer(device, pbp_buf_mem); VkCommandBufferBeginInfo begin_info{}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -319,11 +255,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( return false; } - // Copy back filter_out buffer. - vulkan_copy_buffer(device, command_pool, queue, filter_out_buf, - staging_filter_buffer, size * sizeof(float)); - - vulkan_flush_buffer(device, staging_filter_buffer_mem); + vulkan_flush_buffer(device, filter_out_buf_mem); return true; }; @@ -350,7 +282,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( std::cerr << "Vulkan: Failed to execute get_filter at start!\n"; } else { #ifndef NDEBUG - internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width, + internal::write_filter(vulkan_buf_to_vec(filter_out_mapped, size), width, "filter_out_start.pgm"); #endif } @@ -370,7 +302,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( int min, max; std::tie(min, max) = - internal::filter_minmax_raw_array(filter_mapped_float, size, pbp); + internal::filter_minmax_raw_array(filter_out_mapped, size, pbp); pbp[max] = false; @@ -382,7 +314,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( // get second buffer's min int second_min; std::tie(second_min, std::ignore) = - internal::filter_minmax_raw_array(filter_mapped_float, size, pbp); + internal::filter_minmax_raw_array(filter_out_mapped, size, pbp); if (second_min == max) { pbp[max] = true; @@ -414,7 +346,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( std::cerr << "Vulkan: Failed to execute do_filter (at end)\n"; } else { #ifndef NDEBUG - internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width, + internal::write_filter(vulkan_buf_to_vec(filter_out_mapped, size), width, "filter_out_final.pgm"); FILE *blue_noise_image = fopen("blue_noise.pbm", "w"); fprintf(blue_noise_image, "P1\n%d %d\n", width, height); @@ -451,7 +383,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( #endif get_filter(); std::tie(std::ignore, max) = - internal::filter_minmax_raw_array(filter_mapped_float, size, pbp); + internal::filter_minmax_raw_array(filter_out_mapped, size, pbp); pbp.at(max) = false; dither_array.at(max) = i; #ifndef NDEBUG @@ -475,7 +407,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( #endif get_filter(); std::tie(min, std::ignore) = - internal::filter_minmax_raw_array(filter_mapped_float, size, pbp); + internal::filter_minmax_raw_array(filter_out_mapped, size, pbp); pbp.at(min) = true; dither_array.at(min) = i; #ifndef NDEBUG @@ -491,7 +423,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( image::Bl min_pixels = internal::rangeToBl(dither_array, width); min_pixels.writeToFile(image::file_type::PNG, true, "da_mid_pixels.png"); get_filter(); - internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width, + internal::write_filter(vulkan_buf_to_vec(filter_out_mapped, size), width, "filter_mid.pgm"); image::Bl pbp_image = toBl(pbp, width); pbp_image.writeToFile(image::file_type::PNG, true, "debug_pbp_mid.png"); @@ -505,7 +437,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( #endif get_filter(); std::tie(std::ignore, max) = - internal::filter_minmax_raw_array(filter_mapped_float, size, pbp); + internal::filter_minmax_raw_array(filter_out_mapped, size, pbp); pbp.at(max) = true; dither_array.at(max) = i; #ifndef NDEBUG @@ -521,7 +453,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( #ifndef NDEBUG { get_filter(); - internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width, + internal::write_filter(vulkan_buf_to_vec(filter_out_mapped, size), width, "filter_after.pgm"); image::Bl pbp_image = toBl(pbp, width); pbp_image.writeToFile(image::file_type::PNG, true, "debug_pbp_after.png"); @@ -530,6 +462,7 @@ std::vector dither::internal::blue_noise_vulkan_impl( return dither_array; } + std::vector dither::internal::vulkan_buf_to_vec(float *mapped, unsigned int size) { std::vector v(size); @@ -1009,11 +942,13 @@ image::Bl dither::blue_noise(int width, int height, int threads, VkBuffer filter_out_buf; VkDeviceMemory filter_out_buf_mem; - if (!internal::vulkan_create_buffer(device, phys_device, filter_out_size, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - filter_out_buf, filter_out_buf_mem)) { + if (!internal::vulkan_create_buffer( + device, phys_device, filter_out_size, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + filter_out_buf, filter_out_buf_mem)) { std::clog << "WARNING: Failed to create filter_out buffer!\n"; goto ENDOF_VULKAN; } @@ -1027,14 +962,24 @@ image::Bl dither::blue_noise(int width, int height, int threads, vkFreeMemory(device, *((VkDeviceMemory *)ptr), nullptr); }, &filter_out_buf_mem); + void *filter_out_mapped; + vkMapMemory(device, filter_out_buf_mem, 0, filter_out_size, 0, + &filter_out_mapped); + utility::Cleanup cleanup_filter_out_mapped( + [device](void *ptr) { + vkUnmapMemory(device, *((VkDeviceMemory *)ptr)); + }, + &filter_out_buf_mem); + float *filter_out_mapped_float = (float *)filter_out_mapped; VkBuffer pbp_buf; VkDeviceMemory pbp_buf_mem; - if (!internal::vulkan_create_buffer(device, phys_device, pbp_size, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - pbp_buf, pbp_buf_mem)) { + if (!internal::vulkan_create_buffer( + device, phys_device, pbp_size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + pbp_buf, pbp_buf_mem)) { std::clog << "WARNING: Failed to create pbp buffer!\n"; goto ENDOF_VULKAN; } @@ -1048,6 +993,14 @@ image::Bl dither::blue_noise(int width, int height, int threads, vkFreeMemory(device, *((VkDeviceMemory *)ptr), nullptr); }, &pbp_buf_mem); + void *pbp_mapped; + vkMapMemory(device, pbp_buf_mem, 0, pbp_size, 0, &pbp_mapped); + utility::Cleanup cleanup_pbp_mapped( + [device](void *ptr) { + vkUnmapMemory(device, *((VkDeviceMemory *)ptr)); + }, + &pbp_buf_mem); + int *pbp_mapped_int = (int *)pbp_mapped; VkBuffer other_buf; VkDeviceMemory other_buf_mem; @@ -1224,9 +1177,10 @@ image::Bl dither::blue_noise(int width, int height, int threads, } auto result = dither::internal::blue_noise_vulkan_impl( - device, phys_device, command_buffer, command_pool, compute_queue, - pbp_buf, compute_pipeline, compute_pipeline_layout, - compute_descriptor_set, filter_out_buf, width, height); + device, command_buffer, compute_queue, compute_pipeline, + compute_pipeline_layout, compute_descriptor_set, + filter_out_mapped_float, pbp_mapped_int, filter_out_buf_mem, + pbp_buf_mem, width, height); if (!result.empty()) { return internal::rangeToBl(result, width); } diff --git a/src/blue_noise.hpp b/src/blue_noise.hpp index 7ae7972..2c118be 100644 --- a/src/blue_noise.hpp +++ b/src/blue_noise.hpp @@ -64,11 +64,11 @@ void vulkan_flush_buffer(VkDevice device, VkDeviceMemory memory); void vulkan_invalidate_buffer(VkDevice device, VkDeviceMemory memory); std::vector blue_noise_vulkan_impl( - VkDevice device, VkPhysicalDevice phys_device, - VkCommandBuffer command_buffer, VkCommandPool command_pool, VkQueue queue, - VkBuffer pbp_buf, VkPipeline pipeline, VkPipelineLayout pipeline_layout, - VkDescriptorSet descriptor_set, VkBuffer filter_out_buf, const int width, - const int height); + VkDevice device, VkCommandBuffer command_buffer, VkQueue queue, + VkPipeline pipeline, VkPipelineLayout pipeline_layout, + VkDescriptorSet descriptor_set, float *filter_out_mapped, int *pbp_mapped, + VkDeviceMemory filter_out_buf_mem, VkDeviceMemory pbp_buf_mem, + const int width, const int height); std::vector vulkan_buf_to_vec(float *mapped, unsigned int size); #endif