Compare commits
6 commits
bd7afeb8bd
...
728d872af4
Author | SHA1 | Date | |
---|---|---|---|
728d872af4 | |||
2e6f414baf | |||
97cfcddfb3 | |||
06115a7a2d | |||
52e6a09abd | |||
ef7f623fb3 |
2 changed files with 204 additions and 65 deletions
|
@ -161,6 +161,49 @@ void dither::internal::vulkan_copy_buffer(VkDevice device,
|
||||||
vkFreeCommandBuffers(device, command_pool, 1, &command_buf);
|
vkFreeCommandBuffers(device, command_pool, 1, &command_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dither::internal::vulkan_copy_buffer_pieces(
|
||||||
|
VkDevice device, VkCommandPool command_pool, VkQueue queue,
|
||||||
|
VkBuffer src_buf, VkBuffer dst_buf,
|
||||||
|
const std::vector<std::tuple<VkDeviceSize, VkDeviceSize>> &pieces) {
|
||||||
|
VkCommandBufferAllocateInfo alloc_info{};
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
alloc_info.commandPool = command_pool;
|
||||||
|
alloc_info.commandBufferCount = 1;
|
||||||
|
|
||||||
|
VkCommandBuffer command_buf;
|
||||||
|
vkAllocateCommandBuffers(device, &alloc_info, &command_buf);
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo begin_info{};
|
||||||
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
vkBeginCommandBuffer(command_buf, &begin_info);
|
||||||
|
|
||||||
|
std::vector<VkBufferCopy> regions;
|
||||||
|
for (auto tuple : pieces) {
|
||||||
|
VkBufferCopy copy_region{};
|
||||||
|
copy_region.size = std::get<0>(tuple);
|
||||||
|
copy_region.srcOffset = std::get<1>(tuple);
|
||||||
|
copy_region.dstOffset = std::get<1>(tuple);
|
||||||
|
regions.push_back(copy_region);
|
||||||
|
}
|
||||||
|
vkCmdCopyBuffer(command_buf, src_buf, dst_buf, regions.size(),
|
||||||
|
regions.data());
|
||||||
|
|
||||||
|
vkEndCommandBuffer(command_buf);
|
||||||
|
|
||||||
|
VkSubmitInfo submit_info{};
|
||||||
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submit_info.commandBufferCount = 1;
|
||||||
|
submit_info.pCommandBuffers = &command_buf;
|
||||||
|
|
||||||
|
vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
|
||||||
|
vkQueueWaitIdle(queue);
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(device, command_pool, 1, &command_buf);
|
||||||
|
}
|
||||||
|
|
||||||
void dither::internal::vulkan_flush_buffer(VkDevice device,
|
void dither::internal::vulkan_flush_buffer(VkDevice device,
|
||||||
VkDeviceMemory memory) {
|
VkDeviceMemory memory) {
|
||||||
VkMappedMemoryRange range{};
|
VkMappedMemoryRange range{};
|
||||||
|
@ -175,6 +218,40 @@ void dither::internal::vulkan_flush_buffer(VkDevice device,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dither::internal::vulkan_flush_buffer_pieces(
|
||||||
|
VkDevice device, const VkDeviceSize phys_atom_size, VkDeviceMemory memory,
|
||||||
|
const std::vector<std::tuple<VkDeviceSize, VkDeviceSize>> &pieces) {
|
||||||
|
std::vector<VkMappedMemoryRange> ranges;
|
||||||
|
for (auto tuple : pieces) {
|
||||||
|
VkMappedMemoryRange range{};
|
||||||
|
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||||
|
range.pNext = nullptr;
|
||||||
|
range.memory = memory;
|
||||||
|
range.offset = std::get<1>(tuple);
|
||||||
|
range.size = std::get<0>(tuple);
|
||||||
|
|
||||||
|
// TODO dynamically handle multiple pieces for more efficient flushes.
|
||||||
|
// This may not be necessary if pieces is always size 1.
|
||||||
|
|
||||||
|
if (range.offset % phys_atom_size != 0) {
|
||||||
|
range.offset = (range.offset / phys_atom_size) * phys_atom_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range.size < phys_atom_size) {
|
||||||
|
range.size = phys_atom_size;
|
||||||
|
} else if (range.size % phys_atom_size != 0) {
|
||||||
|
range.size = (range.size / phys_atom_size) * phys_atom_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges.push_back(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vkFlushMappedMemoryRanges(device, ranges.size(), ranges.data()) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
|
std::clog << "WARNING: vulkan_flush_buffer failed!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dither::internal::vulkan_invalidate_buffer(VkDevice device,
|
void dither::internal::vulkan_invalidate_buffer(VkDevice device,
|
||||||
VkDeviceMemory memory) {
|
VkDeviceMemory memory) {
|
||||||
VkMappedMemoryRange range{};
|
VkMappedMemoryRange range{};
|
||||||
|
@ -267,6 +344,15 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
&staging_filter_buffer_mem);
|
&staging_filter_buffer_mem);
|
||||||
float *filter_mapped_float = (float *)filter_mapped;
|
float *filter_mapped_float = (float *)filter_mapped;
|
||||||
|
|
||||||
|
std::vector<std::size_t> changed_indices;
|
||||||
|
|
||||||
|
VkDeviceSize phys_atom_size;
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties props;
|
||||||
|
vkGetPhysicalDeviceProperties(phys_device, &props);
|
||||||
|
phys_atom_size = props.limits.nonCoherentAtomSize;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
printf("Inserting %d pixels into image of max count %d\n", pixel_count,
|
printf("Inserting %d pixels into image of max count %d\n", pixel_count,
|
||||||
|
@ -285,12 +371,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
if (!vulkan_get_filter(
|
||||||
pipeline, pipeline_layout, descriptor_set,
|
device, phys_atom_size, command_buffer, command_pool, queue, pbp_buf,
|
||||||
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
pipeline, pipeline_layout, descriptor_set, filter_out_buf, size, pbp,
|
||||||
pbp_mapped_int, staging_pbp_buffer,
|
reversed_pbp, global_size, pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
staging_filter_buffer)) {
|
staging_filter_buffer, nullptr)) {
|
||||||
std::cerr << "Vulkan: Failed to execute get_filter at start!\n";
|
std::cerr << "Vulkan: Failed to execute get_filter at start!\n";
|
||||||
} else {
|
} else {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -309,12 +395,13 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
printf("Iteration %d\n", ++iterations);
|
printf("Iteration %d\n", ++iterations);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
if (!vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pipeline, pipeline_layout, descriptor_set,
|
queue, pbp_buf, pipeline, pipeline_layout,
|
||||||
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
descriptor_set, filter_out_buf, size, pbp,
|
||||||
pbp_mapped_int, staging_pbp_buffer,
|
reversed_pbp, global_size, pbp_mapped_int,
|
||||||
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
staging_pbp_buffer, staging_pbp_buffer_mem,
|
||||||
staging_filter_buffer)) {
|
staging_filter_buffer_mem, staging_filter_buffer,
|
||||||
|
&changed_indices)) {
|
||||||
std::cerr << "Vulkan: Failed to execute do_filter\n";
|
std::cerr << "Vulkan: Failed to execute do_filter\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -343,12 +430,15 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
|
|
||||||
pbp[max] = false;
|
pbp[max] = false;
|
||||||
|
|
||||||
if (!vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
changed_indices.push_back(max);
|
||||||
pipeline, pipeline_layout, descriptor_set,
|
|
||||||
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
if (!vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pbp_mapped_int, staging_pbp_buffer,
|
queue, pbp_buf, pipeline, pipeline_layout,
|
||||||
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
descriptor_set, filter_out_buf, size, pbp,
|
||||||
staging_filter_buffer)) {
|
reversed_pbp, global_size, pbp_mapped_int,
|
||||||
|
staging_pbp_buffer, staging_pbp_buffer_mem,
|
||||||
|
staging_filter_buffer_mem, staging_filter_buffer,
|
||||||
|
&changed_indices)) {
|
||||||
std::cerr << "Vulkan: Failed to execute do_filter\n";
|
std::cerr << "Vulkan: Failed to execute do_filter\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -369,9 +459,11 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
|
|
||||||
if (second_min == max) {
|
if (second_min == max) {
|
||||||
pbp[max] = true;
|
pbp[max] = true;
|
||||||
|
changed_indices.push_back(max);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
pbp[second_min] = true;
|
pbp[second_min] = true;
|
||||||
|
changed_indices.push_back(second_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -393,12 +485,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
if (!vulkan_get_filter(
|
||||||
pipeline, pipeline_layout, descriptor_set,
|
device, phys_atom_size, command_buffer, command_pool, queue, pbp_buf,
|
||||||
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
pipeline, pipeline_layout, descriptor_set, filter_out_buf, size, pbp,
|
||||||
pbp_mapped_int, staging_pbp_buffer,
|
reversed_pbp, global_size, pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
staging_filter_buffer)) {
|
staging_filter_buffer, &changed_indices)) {
|
||||||
std::cerr << "Vulkan: Failed to execute do_filter (at end)\n";
|
std::cerr << "Vulkan: Failed to execute do_filter (at end)\n";
|
||||||
} else {
|
} else {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -437,12 +529,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cout << i << ' ';
|
std::cout << i << ' ';
|
||||||
#endif
|
#endif
|
||||||
vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pipeline, pipeline_layout, descriptor_set,
|
queue, pbp_buf, pipeline, pipeline_layout,
|
||||||
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
descriptor_set, filter_out_buf, size, pbp, reversed_pbp,
|
||||||
pbp_mapped_int, staging_pbp_buffer,
|
global_size, pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
staging_filter_buffer);
|
staging_filter_buffer, &changed_indices);
|
||||||
auto vulkan_minmax_opt = vulkan_minmax(
|
auto vulkan_minmax_opt = vulkan_minmax(
|
||||||
device, phys_device, command_buffer, command_pool, queue,
|
device, phys_device, command_buffer, command_pool, queue,
|
||||||
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
||||||
|
@ -456,6 +548,7 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
std::tie(std::ignore, max) = vulkan_minmax_opt.value();
|
std::tie(std::ignore, max) = vulkan_minmax_opt.value();
|
||||||
pbp.at(max) = false;
|
pbp.at(max) = false;
|
||||||
dither_array.at(max) = i;
|
dither_array.at(max) = i;
|
||||||
|
changed_indices.push_back(max);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (set.find(max) != set.end()) {
|
if (set.find(max) != set.end()) {
|
||||||
std::cout << "\nWARNING: Reusing index " << max << '\n';
|
std::cout << "\nWARNING: Reusing index " << max << '\n';
|
||||||
|
@ -475,11 +568,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cout << i << ' ';
|
std::cout << i << ' ';
|
||||||
#endif
|
#endif
|
||||||
vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pipeline, pipeline_layout, descriptor_set, filter_out_buf,
|
queue, pbp_buf, pipeline, pipeline_layout, descriptor_set,
|
||||||
size, pbp, reversed_pbp, global_size, pbp_mapped_int,
|
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
||||||
staging_pbp_buffer, staging_pbp_buffer_mem,
|
pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_filter_buffer_mem, staging_filter_buffer);
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
|
staging_filter_buffer, &changed_indices);
|
||||||
auto vulkan_minmax_opt = vulkan_minmax(
|
auto vulkan_minmax_opt = vulkan_minmax(
|
||||||
device, phys_device, command_buffer, command_pool, queue,
|
device, phys_device, command_buffer, command_pool, queue,
|
||||||
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
||||||
|
@ -493,6 +587,7 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
std::tie(min, std::ignore) = vulkan_minmax_opt.value();
|
std::tie(min, std::ignore) = vulkan_minmax_opt.value();
|
||||||
pbp.at(min) = true;
|
pbp.at(min) = true;
|
||||||
dither_array.at(min) = i;
|
dither_array.at(min) = i;
|
||||||
|
changed_indices.push_back(min);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (set.find(min) != set.end()) {
|
if (set.find(min) != set.end()) {
|
||||||
std::cout << "\nWARNING: Reusing index " << min << '\n';
|
std::cout << "\nWARNING: Reusing index " << min << '\n';
|
||||||
|
@ -505,11 +600,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
{
|
{
|
||||||
image::Bl min_pixels = internal::rangeToBl(dither_array, width);
|
image::Bl min_pixels = internal::rangeToBl(dither_array, width);
|
||||||
min_pixels.writeToFile(image::file_type::PNG, true, "da_mid_pixels.png");
|
min_pixels.writeToFile(image::file_type::PNG, true, "da_mid_pixels.png");
|
||||||
vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pipeline, pipeline_layout, descriptor_set, filter_out_buf,
|
queue, pbp_buf, pipeline, pipeline_layout, descriptor_set,
|
||||||
size, pbp, reversed_pbp, global_size, pbp_mapped_int,
|
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
||||||
staging_pbp_buffer, staging_pbp_buffer_mem,
|
pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_filter_buffer_mem, staging_filter_buffer);
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
|
staging_filter_buffer, &changed_indices);
|
||||||
internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width,
|
internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width,
|
||||||
"filter_mid.pgm");
|
"filter_mid.pgm");
|
||||||
image::Bl pbp_image = toBl(pbp, width);
|
image::Bl pbp_image = toBl(pbp, width);
|
||||||
|
@ -518,15 +614,21 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
#endif
|
#endif
|
||||||
std::cout << "\nRanking last half of pixels...\n";
|
std::cout << "\nRanking last half of pixels...\n";
|
||||||
reversed_pbp = true;
|
reversed_pbp = true;
|
||||||
|
bool first_reversed_run = true;
|
||||||
for (unsigned int i = (size + 1) / 2; i < (unsigned int)size; ++i) {
|
for (unsigned int i = (size + 1) / 2; i < (unsigned int)size; ++i) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cout << i << ' ';
|
std::cout << i << ' ';
|
||||||
#endif
|
#endif
|
||||||
vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
if (first_reversed_run) {
|
||||||
pipeline, pipeline_layout, descriptor_set, filter_out_buf,
|
changed_indices.clear();
|
||||||
size, pbp, reversed_pbp, global_size, pbp_mapped_int,
|
first_reversed_run = false;
|
||||||
staging_pbp_buffer, staging_pbp_buffer_mem,
|
}
|
||||||
staging_filter_buffer_mem, staging_filter_buffer);
|
vulkan_get_filter(device, phys_atom_size, 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, &changed_indices);
|
||||||
auto vulkan_minmax_opt = vulkan_minmax(
|
auto vulkan_minmax_opt = vulkan_minmax(
|
||||||
device, phys_device, command_buffer, command_pool, queue,
|
device, phys_device, command_buffer, command_pool, queue,
|
||||||
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
minmax_pipeline, minmax_pipeline_layout, minmax_desc_sets, max_in_buf,
|
||||||
|
@ -540,6 +642,7 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
std::tie(std::ignore, max) = vulkan_minmax_opt.value();
|
std::tie(std::ignore, max) = vulkan_minmax_opt.value();
|
||||||
pbp.at(max) = true;
|
pbp.at(max) = true;
|
||||||
dither_array.at(max) = i;
|
dither_array.at(max) = i;
|
||||||
|
changed_indices.push_back(max);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (set.find(max) != set.end()) {
|
if (set.find(max) != set.end()) {
|
||||||
std::cout << "\nWARNING: Reusing index " << max << '\n';
|
std::cout << "\nWARNING: Reusing index " << max << '\n';
|
||||||
|
@ -552,11 +655,12 @@ std::vector<unsigned int> dither::internal::blue_noise_vulkan_impl(
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
vulkan_get_filter(device, command_buffer, command_pool, queue, pbp_buf,
|
vulkan_get_filter(device, phys_atom_size, command_buffer, command_pool,
|
||||||
pipeline, pipeline_layout, descriptor_set, filter_out_buf,
|
queue, pbp_buf, pipeline, pipeline_layout, descriptor_set,
|
||||||
size, pbp, reversed_pbp, global_size, pbp_mapped_int,
|
filter_out_buf, size, pbp, reversed_pbp, global_size,
|
||||||
staging_pbp_buffer, staging_pbp_buffer_mem,
|
pbp_mapped_int, staging_pbp_buffer,
|
||||||
staging_filter_buffer_mem, staging_filter_buffer);
|
staging_pbp_buffer_mem, staging_filter_buffer_mem,
|
||||||
|
staging_filter_buffer, nullptr);
|
||||||
internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width,
|
internal::write_filter(vulkan_buf_to_vec(filter_mapped_float, size), width,
|
||||||
"filter_after.pgm");
|
"filter_after.pgm");
|
||||||
image::Bl pbp_image = toBl(pbp, width);
|
image::Bl pbp_image = toBl(pbp, width);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <tuple>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -66,8 +67,15 @@ void vulkan_copy_buffer(VkDevice device, VkCommandPool command_pool,
|
||||||
VkQueue queue, VkBuffer src_buf, VkBuffer dst_buf,
|
VkQueue queue, VkBuffer src_buf, VkBuffer dst_buf,
|
||||||
VkDeviceSize size, VkDeviceSize src_offset = 0,
|
VkDeviceSize size, VkDeviceSize src_offset = 0,
|
||||||
VkDeviceSize dst_offset = 0);
|
VkDeviceSize dst_offset = 0);
|
||||||
|
void vulkan_copy_buffer_pieces(
|
||||||
|
VkDevice device, VkCommandPool command_pool, VkQueue queue,
|
||||||
|
VkBuffer src_buf, VkBuffer dst_buf,
|
||||||
|
const std::vector<std::tuple<VkDeviceSize, VkDeviceSize> > &pieces);
|
||||||
|
|
||||||
void vulkan_flush_buffer(VkDevice device, VkDeviceMemory memory);
|
void vulkan_flush_buffer(VkDevice device, VkDeviceMemory memory);
|
||||||
|
void vulkan_flush_buffer_pieces(
|
||||||
|
VkDevice device, const VkDeviceSize phys_atom_size, VkDeviceMemory memory,
|
||||||
|
const std::vector<std::tuple<VkDeviceSize, VkDeviceSize> > &pieces);
|
||||||
void vulkan_invalidate_buffer(VkDevice device, VkDeviceMemory memory);
|
void vulkan_invalidate_buffer(VkDevice device, VkDeviceMemory memory);
|
||||||
|
|
||||||
std::vector<unsigned int> blue_noise_vulkan_impl(
|
std::vector<unsigned int> blue_noise_vulkan_impl(
|
||||||
|
@ -85,30 +93,57 @@ std::vector<unsigned int> blue_noise_vulkan_impl(
|
||||||
std::vector<float> vulkan_buf_to_vec(float *mapped, unsigned int size);
|
std::vector<float> vulkan_buf_to_vec(float *mapped, unsigned int size);
|
||||||
|
|
||||||
inline bool vulkan_get_filter(
|
inline bool vulkan_get_filter(
|
||||||
VkDevice device, VkCommandBuffer command_buffer, VkCommandPool command_pool,
|
VkDevice device, const VkDeviceSize phys_atom_size,
|
||||||
VkQueue queue, VkBuffer pbp_buf, VkPipeline pipeline,
|
VkCommandBuffer command_buffer, VkCommandPool command_pool, VkQueue queue,
|
||||||
VkPipelineLayout pipeline_layout, VkDescriptorSet descriptor_set,
|
VkBuffer pbp_buf, VkPipeline pipeline, VkPipelineLayout pipeline_layout,
|
||||||
VkBuffer filter_out_buf, const int size, std::vector<bool> &pbp,
|
VkDescriptorSet descriptor_set, VkBuffer filter_out_buf, const int size,
|
||||||
bool reversed_pbp, const std::size_t global_size, int *pbp_mapped_int,
|
std::vector<bool> &pbp, bool reversed_pbp, const std::size_t global_size,
|
||||||
VkBuffer staging_pbp_buffer, VkDeviceMemory staging_pbp_buffer_mem,
|
int *pbp_mapped_int, VkBuffer staging_pbp_buffer,
|
||||||
VkDeviceMemory staging_filter_buffer_mem, VkBuffer staging_filter_buffer) {
|
VkDeviceMemory staging_pbp_buffer_mem,
|
||||||
|
VkDeviceMemory staging_filter_buffer_mem, VkBuffer staging_filter_buffer,
|
||||||
|
std::vector<std::size_t> *changed) {
|
||||||
vkResetCommandBuffer(command_buffer, 0);
|
vkResetCommandBuffer(command_buffer, 0);
|
||||||
|
|
||||||
if (reversed_pbp) {
|
if (changed != nullptr && changed->size() > 0) {
|
||||||
for (unsigned int i = 0; i < pbp.size(); ++i) {
|
if (reversed_pbp) {
|
||||||
pbp_mapped_int[i] = pbp[i] ? 0 : 1;
|
for (auto idx : *changed) {
|
||||||
|
pbp_mapped_int[idx] = pbp[idx] ? 0 : 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto idx : *changed) {
|
||||||
|
pbp_mapped_int[idx] = pbp[idx] ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (unsigned int i = 0; i < pbp.size(); ++i) {
|
if (reversed_pbp) {
|
||||||
pbp_mapped_int[i] = pbp[i] ? 1 : 0;
|
for (unsigned int i = 0; i < pbp.size(); ++i) {
|
||||||
|
pbp_mapped_int[i] = pbp[i] ? 0 : 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned int i = 0; i < pbp.size(); ++i) {
|
||||||
|
pbp_mapped_int[i] = pbp[i] ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vulkan_flush_buffer(device, staging_pbp_buffer_mem);
|
|
||||||
|
|
||||||
// Copy pbp buffer.
|
// Copy pbp buffer.
|
||||||
vulkan_copy_buffer(device, command_pool, queue, staging_pbp_buffer, pbp_buf,
|
if (changed != nullptr && changed->size() > 0) {
|
||||||
size * sizeof(int));
|
std::vector<std::tuple<VkDeviceSize, VkDeviceSize> > pieces;
|
||||||
|
for (auto idx : *changed) {
|
||||||
|
pieces.emplace_back(std::make_tuple(sizeof(int), idx * sizeof(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
vulkan_flush_buffer_pieces(device, phys_atom_size, staging_pbp_buffer_mem,
|
||||||
|
pieces);
|
||||||
|
|
||||||
|
vulkan_copy_buffer_pieces(device, command_pool, queue, staging_pbp_buffer,
|
||||||
|
pbp_buf, pieces);
|
||||||
|
changed->clear();
|
||||||
|
} else {
|
||||||
|
vulkan_flush_buffer(device, staging_pbp_buffer_mem);
|
||||||
|
vulkan_copy_buffer(device, command_pool, queue, staging_pbp_buffer, pbp_buf,
|
||||||
|
size * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBufferBeginInfo begin_info{};
|
VkCommandBufferBeginInfo begin_info{};
|
||||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
|
Loading…
Reference in a new issue