From 1a8cf1e6a3a993132fbbef9c663b3a0787637f39 Mon Sep 17 00:00:00 2001 From: Jens Koenen <koenen@vr.rwth-aachen.de> Date: Wed, 14 Sep 2022 23:23:42 +0200 Subject: [PATCH] The scene is now voxelized and later used during the propagation of the light. --- liblava/block/pipeline.hpp | 6 + res/dpr/utility/indirect_geometry.frag | 26 +- res/dpr/utility/indirect_geometry.geom | 36 ++- res/dpr/utility/indirect_propagation.comp | 33 ++- src/utility/indirect_cache.cpp | 331 ++++++++++------------ src/utility/indirect_cache.hpp | 9 +- src/vr_application.cpp | 1 + 7 files changed, 232 insertions(+), 210 deletions(-) diff --git a/liblava/block/pipeline.hpp b/liblava/block/pipeline.hpp index 49e9713f..a3b8fa14 100644 --- a/liblava/block/pipeline.hpp +++ b/liblava/block/pipeline.hpp @@ -284,6 +284,9 @@ namespace lava { void set_viewport(VkViewport value) { viewport = value; } + void set_viewport_count(uint32_t count){ + info.viewport_state.viewportCount = count; + } VkRect2D get_scissor() const { return scissor; @@ -291,6 +294,9 @@ namespace lava { void set_scissor(VkRect2D value) { scissor = value; } + void set_scissor_count(uint32_t count) { + info.viewport_state.scissorCount = count; + } size_type get_size_type() const { return size_type; diff --git a/res/dpr/utility/indirect_geometry.frag b/res/dpr/utility/indirect_geometry.frag index 3aa83d02..13f593f0 100644 --- a/res/dpr/utility/indirect_geometry.frag +++ b/res/dpr/utility/indirect_geometry.frag @@ -1,6 +1,5 @@ #version 450 core #extension GL_GOOGLE_include_directive : require -#extension GL_EXT_shader_atomic_float : require #include "indirect_data.inc" #include "indirect_library.glsl" @@ -10,10 +9,8 @@ layout(set = 1, binding = 0) uniform IndirectDomainBuffer IndirectDomain indirect_domain; }; -layout(set = 1, binding = 1, r32f) uniform image3D image_geometry_x_distribution; -layout(set = 1, binding = 2, r32f) uniform image3D image_geometry_y_distribution; -layout(set = 1, binding = 3, r32f) uniform image3D image_geometry_z_distribution; -layout(set = 1, binding = 4, r32f) uniform image3D image_geometry_w_distribution; +layout(set = 1, binding = 1, r32ui) uniform uimage3D image_geometry_xy_distribution; +layout(set = 1, binding = 2, r32ui) uniform uimage3D image_geometry_zw_distribution; layout(push_constant) uniform Constants { @@ -23,6 +20,19 @@ layout(push_constant) uniform Constants layout(location = 0) in vec3 inCoord; layout(location = 1) in vec3 inNormal; +#define atomicAdd(image, coord, value) \ +{ \ + uint new_value = packHalf2x16(value); \ + uint previous_value = 0; \ + uint current_value = 0; \ + \ + while((current_value = imageAtomicCompSwap(image, coord, previous_value, new_value)) != previous_value) \ + { \ + previous_value = current_value; \ + new_value = packHalf2x16(value + unpackHalf2x16(current_value)); \ + } \ +} + void main() { ivec3 cell_coord = ivec3(inCoord * indirect_domain.geometry_resolution); @@ -51,8 +61,6 @@ void main() //NOTE: Where opacity is in percent vec4 geometry_distribution = opacity * distribution; - imageAtomicAdd(image_geometry_x_distribution, cell_coord, geometry_distribution.x); - imageAtomicAdd(image_geometry_y_distribution, cell_coord, geometry_distribution.y); - imageAtomicAdd(image_geometry_z_distribution, cell_coord, geometry_distribution.z); - imageAtomicAdd(image_geometry_w_distribution, cell_coord, geometry_distribution.w); + atomicAdd(image_geometry_xy_distribution, cell_coord, geometry_distribution.xy); + atomicAdd(image_geometry_zw_distribution, cell_coord, geometry_distribution.zw); } \ No newline at end of file diff --git a/res/dpr/utility/indirect_geometry.geom b/res/dpr/utility/indirect_geometry.geom index b63bf132..1227568c 100644 --- a/res/dpr/utility/indirect_geometry.geom +++ b/res/dpr/utility/indirect_geometry.geom @@ -22,45 +22,57 @@ void main() vec3 position2 = gl_in[1].gl_Position.xyz; vec3 position3 = gl_in[2].gl_Position.xyz; + vec3 coord1 = (position1 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + vec3 coord2 = (position2 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + vec3 coord3 = (position3 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + + vec2 screen_coord1 = vec2(0.0); + vec2 screen_coord2 = vec2(0.0); + vec2 screen_coord3 = vec2(0.0); + vec3 normal_abs = abs(cross(position2 - position1, position3 - position1)); float normal_max = max(normal_abs.x, max(normal_abs.y, normal_abs.z)); if(normal_abs.x == normal_max) { - position1 = position1.yzx; - position2 = position2.yzx; - position3 = position3.yzx; + screen_coord1 = coord1.yz; + screen_coord2 = coord2.yz; + screen_coord3 = coord3.yz; gl_ViewportIndex = 0; } else if(normal_abs.y == normal_max) { - position1 = position1.xzy; - position2 = position2.xzy; - position3 = position3.xzy; + screen_coord1 = coord1.xz; + screen_coord2 = coord2.xz; + screen_coord3 = coord3.xz; gl_ViewportIndex = 1; } else { + screen_coord1 = coord1.xy; + screen_coord2 = coord2.xy; + screen_coord3 = coord3.xy; + gl_ViewportIndex = 2; } - outCoord = (position1 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + outCoord = coord1; outNormal = inNormal[0]; - gl_Position = vec4(outCoord.xy * 2.0 - 1.0, 0.5, 1.0); + gl_Position = vec4(screen_coord1 * 2.0 - 1.0, 0.5, 1.0); EmitVertex(); - outCoord = (position2 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + outCoord = coord2; outNormal = inNormal[1]; - gl_Position = vec4(outCoord.xy * 2.0 - 1.0, 0.5, 1.0); + gl_Position = vec4(screen_coord2 * 2.0 - 1.0, 0.5, 1.0); EmitVertex(); - outCoord = (position3 - indirect_domain.min) / (indirect_domain.max - indirect_domain.min); + outCoord = coord3; outNormal = inNormal[2]; - gl_Position = vec4(outCoord.xy * 2.0 - 1.0, 0.5, 1.0); + gl_Position = vec4(screen_coord3 * 2.0 - 1.0, 0.5, 1.0); EmitVertex(); EndPrimitive(); diff --git a/res/dpr/utility/indirect_propagation.comp b/res/dpr/utility/indirect_propagation.comp index f77b617b..62cb6356 100644 --- a/res/dpr/utility/indirect_propagation.comp +++ b/res/dpr/utility/indirect_propagation.comp @@ -18,7 +18,10 @@ layout(set = 0, binding = 6, rgba16f) uniform image3D image_red_indirect; layout(set = 0, binding = 7, rgba16f) uniform image3D image_green_indirect; layout(set = 0, binding = 8, rgba16f) uniform image3D image_blue_indirect; -layout(set = 0, binding = 9) uniform IndirectDomainBuffer +layout(set = 0, binding = 9) uniform sampler3D sampler_geometry_xy_distribution; +layout(set = 0, binding = 10) uniform sampler3D sampler_geometry_zy_distribution; + +layout(set = 0, binding = 11) uniform IndirectDomainBuffer { IndirectDomain indirect_domain; }; @@ -73,6 +76,11 @@ bool check_bounds(ivec3 coord) return all(lessThanEqual(ivec3(0), coord)) && all(lessThan(coord, indirect_domain.indirect_resolution)); } +vec4 load_geometry_distribution(vec3 geometry_coord) +{ + return vec4(0.0); //TODO: !!! +} + void propagate_neighbour(ivec3 cell_coord, uint neighbour, inout vec4 red_distribution, inout vec4 green_distribution, inout vec4 blue_distribution) { ivec3 neighbour_coord = cell_coord + neighbour_offsets[neighbour]; @@ -83,12 +91,19 @@ void propagate_neighbour(ivec3 cell_coord, uint neighbour, inout vec4 red_distri return; } + //----- Visibility ---------------------------------------------- + + vec3 geometry_coord = (vec3(cell_coord) + vec3(neighbour_coord)) / 2.0; + vec4 geometry_distribution = load_geometry_distribution(geometry_coord); + + float visibility = 1.0; //TODO:!!! + + //----- Side Faces ---------------------------------------------- + vec4 neighbour_red_distribution = imageLoad(image_src_red_distribution, neighbour_coord); vec4 neighbour_green_distribution = imageLoad(image_src_green_distribution, neighbour_coord); vec4 neighbour_blue_distribution = imageLoad(image_src_blue_distribution, neighbour_coord); - //----- Side Faces ---------------------------------------------- - for(uint side = 0; side < 4; side++) { vec3 eval_direction = neighbour_orientation * side_eval_directions[side]; @@ -100,9 +115,9 @@ void propagate_neighbour(ivec3 cell_coord, uint neighbour, inout vec4 red_distri intensity.z = max(0.0, spherical_harmonic_evaluate(eval_direction, neighbour_blue_distribution)); //NOTE: Where side_solid_angle * intensity is in watt - red_distribution += (side_solid_angle * intensity.x) * spherical_harmonic_cosine_lobe(emit_direction); - green_distribution += (side_solid_angle * intensity.y) * spherical_harmonic_cosine_lobe(emit_direction); - blue_distribution += (side_solid_angle * intensity.z) * spherical_harmonic_cosine_lobe(emit_direction); + red_distribution += (side_solid_angle * intensity.x) * visibility * spherical_harmonic_cosine_lobe(emit_direction); + green_distribution += (side_solid_angle * intensity.y) * visibility * spherical_harmonic_cosine_lobe(emit_direction); + blue_distribution += (side_solid_angle * intensity.z) * visibility * spherical_harmonic_cosine_lobe(emit_direction); } //----- Direct Face ----------------------------------------------- @@ -116,9 +131,9 @@ void propagate_neighbour(ivec3 cell_coord, uint neighbour, inout vec4 red_distri intensity.z = max(0.0, spherical_harmonic_evaluate(eval_direction, neighbour_blue_distribution)); //NOTE: Where side_solid_angle * intensity is in watt - red_distribution += (direct_solid_angle * intensity.x) * spherical_harmonic_cosine_lobe(emit_direction); - green_distribution += (direct_solid_angle * intensity.y) * spherical_harmonic_cosine_lobe(emit_direction); - blue_distribution += (direct_solid_angle * intensity.z) * spherical_harmonic_cosine_lobe(emit_direction); + red_distribution += (direct_solid_angle * intensity.x) * visibility * spherical_harmonic_cosine_lobe(emit_direction); + green_distribution += (direct_solid_angle * intensity.y) * visibility * spherical_harmonic_cosine_lobe(emit_direction); + blue_distribution += (direct_solid_angle * intensity.z) * visibility * spherical_harmonic_cosine_lobe(emit_direction); //----------------------------------------------------------------- } diff --git a/src/utility/indirect_cache.cpp b/src/utility/indirect_cache.cpp index b13858db..a5634a7d 100644 --- a/src/utility/indirect_cache.cpp +++ b/src/utility/indirect_cache.cpp @@ -198,10 +198,14 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index { const std::vector<SceneLight>& lights = this->scene->get_lights(); - VkImageMemoryBarrier clear_geometry_begin_barrier = IndirectCache::build_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - clear_geometry_begin_barrier.image = this->distribution_geometry_image; + std::vector<VkImageMemoryBarrier> clear_begin_barriers = IndirectCache::build_barriers(5, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + clear_begin_barriers[0].image = this->distribution_red_image[0]; + clear_begin_barriers[1].image = this->distribution_green_image[0]; + clear_begin_barriers[2].image = this->distribution_blue_image[0]; + clear_begin_barriers[3].image = this->distribution_geometry_image[0]; + clear_begin_barriers[4].image = this->distribution_geometry_image[1]; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &clear_geometry_begin_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, clear_begin_barriers.size(), clear_begin_barriers.data()); VkClearColorValue clear_color; clear_color.float32[0] = 0.0f; @@ -216,36 +220,33 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index subresource_range.baseArrayLayer = 0; subresource_range.layerCount = 1; - vkCmdClearColorImage(command_buffer, this->distribution_geometry_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); - - VkImageMemoryBarrier clear_geometry_end_barrier = IndirectCache::build_barrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); - clear_geometry_end_barrier.image = this->distribution_geometry_image; - - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &clear_geometry_end_barrier); - - this->geometry_pass->process(command_buffer, 0); - - - //TODO: Another layout transition to shader ead only optimal - - std::array<VkImageMemoryBarrier, 3> clear_begin_barriers = IndirectCache::build_barriers(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - clear_begin_barriers[0].image = this->distribution_red_image[0]; - clear_begin_barriers[1].image = this->distribution_green_image[0]; - clear_begin_barriers[2].image = this->distribution_blue_image[0]; - - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, clear_begin_barriers.size(), clear_begin_barriers.data()); - vkCmdClearColorImage(command_buffer, this->distribution_red_image[0], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); vkCmdClearColorImage(command_buffer, this->distribution_green_image[0], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); vkCmdClearColorImage(command_buffer, this->distribution_blue_image[0], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); + vkCmdClearColorImage(command_buffer, this->distribution_geometry_image[0], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); + vkCmdClearColorImage(command_buffer, this->distribution_geometry_image[1], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource_range); - std::array<VkImageMemoryBarrier, 3> clear_end_barriers = IndirectCache::build_barriers(VK_ACCESS_TRANSFER_WRITE_BIT, 0, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + std::vector<VkImageMemoryBarrier> clear_end_barriers = IndirectCache::build_barriers(3, VK_ACCESS_TRANSFER_WRITE_BIT, 0, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); clear_end_barriers[0].image = this->distribution_red_image[0]; clear_end_barriers[1].image = this->distribution_green_image[0]; clear_end_barriers[2].image = this->distribution_blue_image[0]; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, clear_end_barriers.size(), clear_end_barriers.data()); + std::vector<VkImageMemoryBarrier> geometry_begin_barriers = IndirectCache::build_barriers(2, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); + geometry_begin_barriers[0].image = this->distribution_geometry_image[0]; + geometry_begin_barriers[1].image = this->distribution_geometry_image[1]; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, geometry_begin_barriers.size(), geometry_begin_barriers.data()); + + this->geometry_pass->process(command_buffer, 0); + + std::vector<VkImageMemoryBarrier> geometry_end_barriers = IndirectCache::build_barriers(2, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + geometry_end_barriers[0].image = this->distribution_geometry_image[0]; + geometry_end_barriers[1].image = this->distribution_geometry_image[1]; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, geometry_end_barriers.size(), geometry_end_barriers.data()); + for (uint32_t index = 0; index < lights.size(); index++) { const SceneLight& light = lights[index]; @@ -264,7 +265,7 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index //NOTE: Memory barrier for source image provieded by injection render pass // The final image layout of distribution_..._image[0] has to be VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL - std::array<VkImageMemoryBarrier, 3> copy_barriers = IndirectCache::build_barriers(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + std::vector<VkImageMemoryBarrier> copy_barriers = IndirectCache::build_barriers(3, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); copy_barriers[0].image = this->distribution_red_image[2]; copy_barriers[1].image = this->distribution_green_image[2]; copy_barriers[2].image = this->distribution_blue_image[2]; @@ -298,21 +299,21 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index vkCmdCopyImage(command_buffer, this->distribution_green_image[0], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, this->distribution_green_image[2], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); vkCmdCopyImage(command_buffer, this->distribution_blue_image[0], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, this->distribution_blue_image[2], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy); - std::array<VkImageMemoryBarrier, 3> setup_src_barriers = IndirectCache::build_barriers(VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> setup_src_barriers = IndirectCache::build_barriers(3, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); setup_src_barriers[0].image = this->distribution_red_image[0]; setup_src_barriers[1].image = this->distribution_green_image[0]; setup_src_barriers[2].image = this->distribution_blue_image[0]; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, setup_src_barriers.size(), setup_src_barriers.data()); - std::array<VkImageMemoryBarrier, 3> setup_dst_barriers = IndirectCache::build_barriers(0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> setup_dst_barriers = IndirectCache::build_barriers(3, 0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); setup_dst_barriers[0].image = this->distribution_red_image[1]; setup_dst_barriers[1].image = this->distribution_green_image[1]; setup_dst_barriers[2].image = this->distribution_blue_image[1]; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, setup_dst_barriers.size(), setup_dst_barriers.data()); - std::array<VkImageMemoryBarrier, 3> setup_indirect_barriers = IndirectCache::build_barriers(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> setup_indirect_barriers = IndirectCache::build_barriers(3, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL); setup_indirect_barriers[0].image = this->distribution_red_image[2]; setup_indirect_barriers[1].image = this->distribution_green_image[2]; setup_indirect_barriers[2].image = this->distribution_blue_image[2]; @@ -330,21 +331,21 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index vkCmdDispatch(command_buffer, this->domain_work_groups.x, this->domain_work_groups.y, this->domain_work_groups.z); - std::array<VkImageMemoryBarrier, 3> compue_src_barriers = IndirectCache::build_barriers(VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> compue_src_barriers = IndirectCache::build_barriers(3, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); compue_src_barriers[0].image = this->distribution_red_image[src_index]; compue_src_barriers[1].image = this->distribution_green_image[src_index]; compue_src_barriers[2].image = this->distribution_blue_image[src_index]; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, compue_src_barriers.size(), compue_src_barriers.data()); - std::array<VkImageMemoryBarrier, 3> compute_dst_barriers = IndirectCache::build_barriers(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> compute_dst_barriers = IndirectCache::build_barriers(3, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); compute_dst_barriers[0].image = this->distribution_red_image[dst_index]; compute_dst_barriers[1].image = this->distribution_green_image[dst_index]; compute_dst_barriers[2].image = this->distribution_blue_image[dst_index]; vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, compute_dst_barriers.size(), compute_dst_barriers.data()); - std::array<VkImageMemoryBarrier, 3> compute_indirect_barriers = IndirectCache::build_barriers(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); + std::vector<VkImageMemoryBarrier> compute_indirect_barriers = IndirectCache::build_barriers(3, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL); compute_indirect_barriers[0].image = this->distribution_red_image[2]; compute_indirect_barriers[1].image = this->distribution_green_image[2]; compute_indirect_barriers[2].image = this->distribution_blue_image[2]; @@ -352,7 +353,7 @@ void IndirectCache::compute_indirect(VkCommandBuffer command_buffer, lava::index vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, compute_indirect_barriers.size(), compute_indirect_barriers.data()); } - std::array<VkImageMemoryBarrier, 3> final_barriers = IndirectCache::build_barriers(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + std::vector<VkImageMemoryBarrier> final_barriers = IndirectCache::build_barriers(3, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); final_barriers[0].image = this->distribution_red_image[2]; final_barriers[1].image = this->distribution_green_image[2]; final_barriers[2].image = this->distribution_blue_image[2]; @@ -540,173 +541,127 @@ bool IndirectCache::create_images(lava::device_ptr device, const IndirectCacheSe for (uint32_t index = 0; index < this->distribution_red_image.size(); index++) { - VmaAllocation red_image_memory = VK_NULL_HANDLE; - VmaAllocation green_image_memory = VK_NULL_HANDLE; - VmaAllocation blue_image_memory = VK_NULL_HANDLE; - - VkImage red_image = VK_NULL_HANDLE; - VkImage green_image = VK_NULL_HANDLE; - VkImage blue_image = VK_NULL_HANDLE; - - if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &red_image, &red_image_memory, nullptr) != VK_SUCCESS) + if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &this->distribution_red_image[index], &this->distribution_red_image_memory[index], nullptr) != VK_SUCCESS) { lava::log()->error("Can't create red distribution image for indirect cache!"); return false; } - if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &green_image, &green_image_memory, nullptr) != VK_SUCCESS) + if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &this->distribution_green_image[index], &this->distribution_green_image_memory[index], nullptr) != VK_SUCCESS) { lava::log()->error("Can't create green distribution image for indirect cache!"); return false; } - if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &blue_image, &blue_image_memory, nullptr) != VK_SUCCESS) + if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &this->distribution_blue_image[index], &this->distribution_blue_image_memory[index], nullptr) != VK_SUCCESS) { lava::log()->error("Can't create blue distribution image for indirect cache!"); return false; } - VkImageView red_image_view = VK_NULL_HANDLE; - VkImageView green_image_view = VK_NULL_HANDLE; - VkImageView blue_image_view = VK_NULL_HANDLE; - - VkImageView red_image_array_view = VK_NULL_HANDLE; - VkImageView green_image_array_view = VK_NULL_HANDLE; - VkImageView blue_image_array_view = VK_NULL_HANDLE; - - view_create_info.image = red_image; - array_view_create_info.image = red_image; + view_create_info.image = this->distribution_red_image[index]; + array_view_create_info.image = this->distribution_red_image[index]; - if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &red_image_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &this->distribution_red_image_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create red distribution image view for indirect cache!"); return false; } - if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &red_image_array_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &this->distribution_red_image_array_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create red distribution image array view for indirect cache!"); return false; } - view_create_info.image = green_image; - array_view_create_info.image = green_image; + view_create_info.image = this->distribution_green_image[index]; + array_view_create_info.image = this->distribution_green_image[index]; - if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &green_image_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &this->distribution_green_image_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create green distribution image view for indirect cache!"); return false; } - if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &green_image_array_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &this->distribution_green_image_array_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create green distribution image array view for indirect cache!"); return false; } - view_create_info.image = blue_image; - array_view_create_info.image = blue_image; + view_create_info.image = this->distribution_blue_image[index]; + array_view_create_info.image = this->distribution_blue_image[index]; - if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &blue_image_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &this->distribution_blue_image_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create blue distribution image view for indirect cache!"); return false; } - if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &blue_image_array_view) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &array_view_create_info, lava::memory::alloc(), &this->distribution_blue_image_array_view[index]) != VK_SUCCESS) { lava::log()->error("Can't create blue distribution image array view for indirect cache!"); return false; } - - this->distribution_red_image_memory[index] = red_image_memory; - this->distribution_green_image_memory[index] = green_image_memory; - this->distribution_blue_image_memory[index] = blue_image_memory; - - this->distribution_red_image[index] = red_image; - this->distribution_green_image[index] = green_image; - this->distribution_blue_image[index] = blue_image; - - this->distribution_red_image_view[index] = red_image_view; - this->distribution_green_image_view[index] = green_image_view; - this->distribution_blue_image_view[index] = blue_image_view; - - this->distribution_red_image_array_view[index] = red_image_array_view; - this->distribution_green_image_array_view[index] = green_image_array_view; - this->distribution_blue_image_array_view[index] = blue_image_array_view; } - image_create_info.format = VK_FORMAT_R32_SFLOAT; + image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + image_create_info.format = VK_FORMAT_R16G16_SFLOAT; image_create_info.extent.width = this->domain_geometry_resolution.x; image_create_info.extent.height = this->domain_geometry_resolution.y; image_create_info.extent.depth = this->domain_geometry_resolution.z; + image_create_info.usage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - for (uint32_t index = 0; index < this->distribution_geometry_image.size(); index++) - { - - } + view_create_info.format = VK_FORMAT_R16G16_SFLOAT; + + VkImageViewCreateInfo integer_view_create_info; + integer_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + integer_view_create_info.pNext = nullptr; + integer_view_create_info.flags = 0; + integer_view_create_info.image = VK_NULL_HANDLE; + integer_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D; + integer_view_create_info.format = VK_FORMAT_R32_UINT; + integer_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + integer_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + integer_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + integer_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + integer_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + integer_view_create_info.subresourceRange.baseMipLevel = 0; + integer_view_create_info.subresourceRange.levelCount = 1; + integer_view_create_info.subresourceRange.baseArrayLayer = 0; + integer_view_create_info.subresourceRange.layerCount = 1; - if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &this->distribution_geometry_image, &this->distribution_geometry_image_memory, nullptr) != VK_SUCCESS) + for (uint32_t index = 0; index < this->distribution_geometry_image.size(); index++) { - lava::log()->error("Can't create geometry distribution image for indirect cache!"); + if (vmaCreateImage(device->get_allocator()->get(), &image_create_info, &allocation_info, &this->distribution_geometry_image[index], &this->distribution_geometry_image_memory[index], nullptr) != VK_SUCCESS) + { + lava::log()->error("Can't create geometry distribution image for indirect cache!"); - return false; - } + return false; + } - view_create_info.image = this->distribution_geometry_image; - - if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &this->distribution_geometry_image_view) != VK_SUCCESS) - { - lava::log()->error("Can't create geometry distribution image view for indirect cache!"); + view_create_info.image = this->distribution_geometry_image[index]; + integer_view_create_info.image = this->distribution_geometry_image[index]; - return false; - } + if (vkCreateImageView(device->get(), &view_create_info, lava::memory::alloc(), &this->distribution_geometry_image_view[index]) != VK_SUCCESS) + { + lava::log()->error("Can't create geometry distribution image view for indirect cache!"); - VkImageViewCreateInfo component_view_create_info; - component_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - component_view_create_info.pNext = nullptr; - component_view_create_info.flags = 0; - component_view_create_info.image = this->distribution_geometry_image; - component_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D; - component_view_create_info.format = VK_FORMAT_R16G16B16A16_SFLOAT; - component_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - component_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - component_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - component_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - component_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - component_view_create_info.subresourceRange.baseMipLevel = 0; - component_view_create_info.subresourceRange.levelCount = 1; - component_view_create_info.subresourceRange.baseArrayLayer = 0; - component_view_create_info.subresourceRange.layerCount = 1; - - VkComponentMapping zero_component; - zero_component.r = VK_COMPONENT_SWIZZLE_ZERO; - zero_component.g = VK_COMPONENT_SWIZZLE_ZERO; - zero_component.b = VK_COMPONENT_SWIZZLE_ZERO; - zero_component.a = VK_COMPONENT_SWIZZLE_ZERO; - - std::vector<VkComponentMapping> component_list(4, zero_component); - component_list[0].r = VK_COMPONENT_SWIZZLE_R; - component_list[1].r = VK_COMPONENT_SWIZZLE_G; - component_list[2].r = VK_COMPONENT_SWIZZLE_B; - component_list[3].r = VK_COMPONENT_SWIZZLE_A; - - for (uint32_t index = 0; index < this->distribution_geometry_image_component_view.size(); index++) - { - component_view_create_info.components = component_list[index]; + return false; + } - if (vkCreateImageView(device->get(), &component_view_create_info, lava::memory::alloc(), &this->distribution_geometry_image_component_view[index]) != VK_SUCCESS) + if (vkCreateImageView(device->get(), &integer_view_create_info, lava::memory::alloc(), &this->distribution_geometry_image_integer_view[index]) != VK_SUCCESS) { - lava::log()->error("Can't create geometry distribution image component view for indirect cache!"); + lava::log()->error("Can't create geometry distribution image integer view for indirect cache!"); return false; } @@ -770,8 +725,8 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) lava::VkDescriptorPoolSizes descriptor_type_count = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 5 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 6 }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 22 } + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 10 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 20 } }; this->descriptor_pool = lava::make_descriptor_pool(); @@ -799,11 +754,9 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) this->geometry_descriptor = lava::make_descriptor(); this->geometry_descriptor->add_binding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 0: indirect domain - this->geometry_descriptor->add_binding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 1: geometry distribution x - this->geometry_descriptor->add_binding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 2: geometry distribution y - this->geometry_descriptor->add_binding(3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 3: geometry distribution z - this->geometry_descriptor->add_binding(4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 4: geometry distribution w - + this->geometry_descriptor->add_binding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 1: geometry distribution xy + this->geometry_descriptor->add_binding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT); //descriptor-binding index 2: geometry distribution zw + if (!this->geometry_descriptor->create(device)) { lava::log()->error("Can't create geometry descriptor set layout for indirect cache!"); @@ -825,19 +778,22 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) } this->propagation_descriptor = lava::make_descriptor(); - this->propagation_descriptor->add_binding(0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 0: image red source distribution - this->propagation_descriptor->add_binding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 1: image green source distribution - this->propagation_descriptor->add_binding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 2: image blue source distribution - - this->propagation_descriptor->add_binding(3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 3: image red destination distribution - this->propagation_descriptor->add_binding(4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 4: image green destination distribution - this->propagation_descriptor->add_binding(5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 5: image blue destination distribution + this->propagation_descriptor->add_binding(0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 0: image red source distribution + this->propagation_descriptor->add_binding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 1: image green source distribution + this->propagation_descriptor->add_binding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 2: image blue source distribution + + this->propagation_descriptor->add_binding(3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 3: image red destination distribution + this->propagation_descriptor->add_binding(4, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 4: image green destination distribution + this->propagation_descriptor->add_binding(5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 5: image blue destination distribution - this->propagation_descriptor->add_binding(6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 6: image red indirect - this->propagation_descriptor->add_binding(7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 7: image green indirect - this->propagation_descriptor->add_binding(8, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 8: image blue indirect + this->propagation_descriptor->add_binding(6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 6: image red indirect + this->propagation_descriptor->add_binding(7, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 7: image green indirect + this->propagation_descriptor->add_binding(8, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 8: image blue indirect - this->propagation_descriptor->add_binding(9, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 9: indirect domain + this->propagation_descriptor->add_binding(9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 9: image xz geometrz distribution + this->propagation_descriptor->add_binding(10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 10: image yw geometrz distribution + + this->propagation_descriptor->add_binding(11, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); //descriptor-binding index 11: indirect domain if (!this->propagation_descriptor->create(device)) { @@ -855,8 +811,8 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) std::vector<VkWriteDescriptorSet> descriptor_writes; std::vector<VkDescriptorImageInfo> image_infos; - descriptor_writes.reserve(33); - image_infos.reserve(28); + descriptor_writes.reserve(35); + image_infos.reserve(30); std::vector<VkImageView> indirect_images = { @@ -885,11 +841,11 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) descriptor_write.pTexelBufferView = nullptr; } - for (uint32_t index = 0; index < this->distribution_geometry_image_component_view.size(); index++) + for (uint32_t index = 0; index < this->distribution_geometry_image_integer_view.size(); index++) { VkDescriptorImageInfo& image_info = image_infos.emplace_back(); image_info.sampler = nullptr; - image_info.imageView = this->distribution_geometry_image_component_view[index]; + image_info.imageView = this->distribution_geometry_image_integer_view[index]; image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; VkWriteDescriptorSet& descriptor_write = descriptor_writes.emplace_back(); @@ -974,11 +930,31 @@ bool IndirectCache::create_descriptors(lava::device_ptr device) descriptor_write.pTexelBufferView = nullptr; } + for (uint32_t image_index = 0; image_index < this->distribution_geometry_image_view.size(); image_index++) + { + VkDescriptorImageInfo& image_info = image_infos.emplace_back(); + image_info.sampler = this->geometry_sampler; + image_info.imageView = this->distribution_geometry_image_view[image_index]; + image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet& descriptor_write = descriptor_writes.emplace_back(); + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.pNext = nullptr; + descriptor_write.dstSet = this->propagation_descriptor_set[set_index]; + descriptor_write.dstBinding = 9 + image_index; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorCount = 1; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.pImageInfo = &image_info; + descriptor_write.pBufferInfo = nullptr; + descriptor_write.pTexelBufferView = nullptr; + } + VkWriteDescriptorSet& propagation_domain_write = descriptor_writes.emplace_back(); propagation_domain_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; propagation_domain_write.pNext = nullptr; propagation_domain_write.dstSet = this->propagation_descriptor_set[set_index]; - propagation_domain_write.dstBinding = 9; + propagation_domain_write.dstBinding = 11; propagation_domain_write.dstArrayElement = 0; propagation_domain_write.descriptorCount = 1; propagation_domain_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -1127,6 +1103,8 @@ bool IndirectCache::create_geometry_pipeline(lava::device_ptr device) this->geometry_pipeline = lava::make_graphics_pipeline(device); this->geometry_pipeline->set_layout(this->geometry_layout); this->geometry_pipeline->set_auto_size(false); + this->geometry_pipeline->set_viewport_count(3); + this->geometry_pipeline->set_scissor_count(3); scene->set_vertex_input(this->geometry_pipeline.get()); @@ -1449,29 +1427,33 @@ void IndirectCache::pipeline_geometry(VkCommandBuffer command_buffer) vkCmdPushConstants(command_buffer, this->geometry_layout->get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(uint32_t) * push_constants.size(), push_constants.data()); + std::array<glm::uvec2, 3> resolutions = + { + glm::uvec2(this->domain_voxel_resolution.y, this->domain_voxel_resolution.z), + glm::uvec2(this->domain_voxel_resolution.x, this->domain_voxel_resolution.z), + glm::uvec2(this->domain_voxel_resolution.x, this->domain_voxel_resolution.y) + }; + std::array<VkViewport, 3> viewports; - viewports[0].x = 0.0f; - viewports[0].y = 0.0f; - viewports[0].width = this->domain_voxel_resolution.y; - viewports[0].height = this->domain_voxel_resolution.z; - viewports[0].minDepth = 0.0f; - viewports[0].maxDepth = 1.0f; - - viewports[1].x = 0.0f; - viewports[1].y = 0.0f; - viewports[1].width = this->domain_voxel_resolution.x; - viewports[1].height = this->domain_voxel_resolution.z; - viewports[1].minDepth = 0.0f; - viewports[1].maxDepth = 1.0f; - - viewports[2].x = 0.0f; - viewports[2].y = 0.0f; - viewports[2].width = this->domain_voxel_resolution.x; - viewports[2].height = this->domain_voxel_resolution.y; - viewports[2].minDepth = 0.0f; - viewports[2].maxDepth = 1.0f; + std::array<VkRect2D, 3> scissors; + + for (uint32_t index = 0; index < resolutions.size(); index++) + { + viewports[index].x = 0.0f; + viewports[index].y = 0.0f; + viewports[index].width = resolutions[index].x; + viewports[index].height = resolutions[index].y; + viewports[index].minDepth = 0.0f; + viewports[index].maxDepth = 1.0f; + + scissors[index].offset.x = 0; + scissors[index].offset.y = 0; + scissors[index].extent.width = resolutions[index].x; + scissors[index].extent.height = resolutions[index].y; + } vkCmdSetViewport(command_buffer, 0, 3, viewports.data()); + vkCmdSetScissor(command_buffer, 0, 3, scissors.data()); this->geometry_layout->bind(command_buffer, this->geometry_descriptor_set, 1); @@ -1554,12 +1536,9 @@ VkImageMemoryBarrier IndirectCache::build_barrier(VkAccessFlags src_access, VkAc return barrier; } -std::array<VkImageMemoryBarrier, 3> IndirectCache::build_barriers(VkAccessFlags src_access, VkAccessFlags dst_access, VkImageLayout old_layout, VkImageLayout new_layout) +std::vector<VkImageMemoryBarrier> IndirectCache::build_barriers(uint32_t count, VkAccessFlags src_access, VkAccessFlags dst_access, VkImageLayout old_layout, VkImageLayout new_layout) { - std::array<VkImageMemoryBarrier, 3> barriers; - barriers.fill(build_barrier(src_access, dst_access, old_layout, new_layout)); - - return barriers; + return std::vector<VkImageMemoryBarrier>(count, IndirectCache::build_barrier(src_access, dst_access, old_layout, new_layout)); } IndirectCache::Ptr make_indirect_cache() diff --git a/src/utility/indirect_cache.hpp b/src/utility/indirect_cache.hpp index 5cc5ccc9..1b469cb2 100644 --- a/src/utility/indirect_cache.hpp +++ b/src/utility/indirect_cache.hpp @@ -54,7 +54,7 @@ private: void pipeline_injection(VkCommandBuffer command_buffer); static VkImageMemoryBarrier build_barrier(VkAccessFlags src_access, VkAccessFlags dst_access, VkImageLayout old_layout, VkImageLayout new_layout); - static std::array<VkImageMemoryBarrier, 3> build_barriers(VkAccessFlags src_access, VkAccessFlags dst_access, VkImageLayout old_layout, VkImageLayout new_layout); + static std::vector<VkImageMemoryBarrier> build_barriers(uint32_t count, VkAccessFlags src_access, VkAccessFlags dst_access, VkImageLayout old_layout, VkImageLayout new_layout); private: Scene::Ptr scene; @@ -109,21 +109,22 @@ private: std::array<VmaAllocation, 3> distribution_red_image_memory; std::array<VmaAllocation, 3> distribution_green_image_memory; std::array<VmaAllocation, 3> distribution_blue_image_memory; - std::array<VmaAllocation, 4> distribution_geometry_image_memory; + std::array<VmaAllocation, 2> distribution_geometry_image_memory; std::array<VkImage, 3> distribution_red_image; std::array<VkImage, 3> distribution_green_image; std::array<VkImage, 3> distribution_blue_image; - std::array<VkImage, 4> distribution_geometry_image; + std::array<VkImage, 2> distribution_geometry_image; std::array<VkImageView, 3> distribution_red_image_view; std::array<VkImageView, 3> distribution_green_image_view; std::array<VkImageView, 3> distribution_blue_image_view; - std::array<VkImageView, 4> distribution_geometry_image_view; + std::array<VkImageView, 2> distribution_geometry_image_view; std::array<VkImageView, 3> distribution_red_image_array_view; std::array<VkImageView, 3> distribution_green_image_array_view; std::array<VkImageView, 3> distribution_blue_image_array_view; + std::array<VkImageView, 2> distribution_geometry_image_integer_view; lava::buffer::ptr domain_buffer; }; diff --git a/src/vr_application.cpp b/src/vr_application.cpp index 98860f5b..8ef1c8e3 100644 --- a/src/vr_application.cpp +++ b/src/vr_application.cpp @@ -68,6 +68,7 @@ bool VRApplication::setup(lava::name name, argh::parser cmd_line) parameters.features.geometryShader = true; parameters.features.tessellationShader = true; parameters.features.imageCubeArray = true; + parameters.features.fragmentStoresAndAtomics = true; }; this->app->on_create = [this]() -- GitLab