diff --git a/liblava/resource/image.hpp b/liblava/resource/image.hpp index 98308ff264ab3dbe3639690b5e350fd3944b0550..b24e850e0a77bd642445d3e2db3e3b2c10dcb519 100644 --- a/liblava/resource/image.hpp +++ b/liblava/resource/image.hpp @@ -51,6 +51,14 @@ namespace lava { VkImageSubresourceRange const& get_subresource_range() const { return subresource_range; } + VkImageSubresourceLayers get_subresource_layers(ui32 levelOffset = 0) const { + return VkImageSubresourceLayers{ + .aspectMask = subresource_range.aspectMask, + .mipLevel = subresource_range.baseMipLevel + levelOffset, + .baseArrayLayer = subresource_range.baseArrayLayer, + .layerCount = subresource_range.layerCount + }; + } void set_flags(VkImageCreateFlagBits flags) { info.flags = flags; @@ -78,6 +86,13 @@ namespace lava { info.arrayLayers = layers; } + void set_base_mip_level(ui32 baseMipLevel) { + subresource_range.baseMipLevel = baseMipLevel; + } + void set_base_array_layer(ui32 baseArrayLayer) { + subresource_range.baseArrayLayer = baseArrayLayer; + } + void set_component(VkComponentMapping mapping = {}) { view_info.components = mapping; } diff --git a/src/headset/emulated_headset.cpp b/src/headset/emulated_headset.cpp index f5d0bd76eb2020f93891f6829d6e85f138a6ba75..9ef4bf68a9f7d2c796365b8a0f3aacee1618fb73 100644 --- a/src/headset/emulated_headset.cpp +++ b/src/headset/emulated_headset.cpp @@ -19,12 +19,7 @@ bool EmulatedHeadset::on_create() this->compute_matrices(EYE_LEFT); this->compute_matrices(EYE_RIGHT); - if (!this->create_framebuffer(EYE_LEFT)) - { - return false; - } - - if (!this->create_framebuffer(EYE_RIGHT)) + if (!this->create_framebuffer()) { return false; } @@ -34,8 +29,7 @@ bool EmulatedHeadset::on_create() void EmulatedHeadset::on_destroy() { - this->destroy_framebuffer(EYE_LEFT); - this->destroy_framebuffer(EYE_RIGHT); + this->destroy_framebuffer(); } bool EmulatedHeadset::on_interface() @@ -115,7 +109,7 @@ void EmulatedHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout } VkImageCopy image_region; - image_region.srcSubresource = subresource_layers; + image_region.srcSubresource = frame_image->get_subresource_layers(); image_region.srcOffset.x = 0; image_region.srcOffset.y = 0; image_region.srcOffset.z = 0; @@ -188,6 +182,11 @@ lava::image::ptr EmulatedHeadset::get_framebuffer(FrameId frame_id) const return this->framebuffers[frame_id]; } +lava::image::ptr EmulatedHeadset::get_framebuffer_array() const +{ + return this->framebuffer_array; +} + const char* EmulatedHeadset::get_name() const { return "Emulated Headset"; @@ -198,25 +197,45 @@ bool EmulatedHeadset::is_attached(Controller controller) const return true; } -bool EmulatedHeadset::create_framebuffer(Eye eye) +bool EmulatedHeadset::create_framebuffer() { - lava::image::ptr framebuffer = lava::make_image(this->get_format()); - framebuffer->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + this->framebuffer_array = lava::make_image(this->get_format()); + this->framebuffer_array->set_layer_count(this->framebuffers.size()); + this->framebuffer_array->set_view_type(VK_IMAGE_VIEW_TYPE_2D_ARRAY); + this->framebuffer_array->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) + if (!this->framebuffer_array->create(this->get_application()->get_device(), this->resolution)) { return false; } - this->framebuffers[eye] = framebuffer; + for (uint32_t index = 0; index < this->framebuffers.size(); index++) + { + lava::image::ptr framebuffer = lava::make_image(this->get_format(), this->framebuffer_array->get()); + framebuffer->set_base_array_layer(index); + framebuffer->set_view_type(VK_IMAGE_VIEW_TYPE_2D); + + if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) + { + return false; + } + + this->framebuffers[index] = framebuffer; + } return true; } -void EmulatedHeadset::destroy_framebuffer(Eye eye) +void EmulatedHeadset::destroy_framebuffer() { - this->framebuffers[eye]->destroy(); - this->framebuffers[eye] = nullptr; + for (lava::image::ptr& framebuffer : this->framebuffers) + { + framebuffer->destroy(true); + framebuffer = nullptr; + } + + this->framebuffer_array->destroy(); + this->framebuffer_array = nullptr; } void EmulatedHeadset::compute_matrices(Eye eye) diff --git a/src/headset/emulated_headset.hpp b/src/headset/emulated_headset.hpp index 096ee8d36b9d0713e41e52096bab92e139675721..dc6617eebaefbb05a08637b3f3632c80340e6d7d 100644 --- a/src/headset/emulated_headset.hpp +++ b/src/headset/emulated_headset.hpp @@ -31,14 +31,15 @@ public: const glm::mat4& get_controller_matrix(Controller controller) const override; lava::image::ptr get_framebuffer(FrameId frame_id) const override; + lava::image::ptr get_framebuffer_array() const override; const char* get_name() const override; bool is_attached(Controller controller) const override; private: - bool create_framebuffer(Eye eye); - void destroy_framebuffer(Eye eye); + bool create_framebuffer(); + void destroy_framebuffer(); void compute_matrices(Eye eye); @@ -49,6 +50,7 @@ private: std::array<glm::mat4, 2> projection_matrices; std::array<glm::mat4, 2> controller_matrices; std::array<lava::image::ptr, 2> framebuffers; + lava::image::ptr framebuffer_array; float near_plane = 0.1f; float far_plane = 1000.0f; diff --git a/src/headset/headset.hpp b/src/headset/headset.hpp index 89220b601f5051bd004efc55908b4f779e06e4e3..77aca53b5905fdcfd35317cbb25b9d1161984ba8 100644 --- a/src/headset/headset.hpp +++ b/src/headset/headset.hpp @@ -104,12 +104,21 @@ public: // Returns the controller matrix of the given controller that should be used for rendering. virtual const glm::mat4& get_controller_matrix(Controller controller) const = 0; - // Returns the framebuffer image for the selected eye. + // Returns the framebuffer image for the selected frame id. // In case of an non-remote headset the frame id has to be ether EYE_LEFT or EYE_RIGHT. - // Otherwise the frame id must not exceed the the maximum number of remote frame ids that was set by the active stereo strategy. + // Otherwise the frame id must not exceed the maximum number of remote frame ids that was set by the active stereo strategy. // The images provided by the headset should support sampling, src and dest transfer operations as well as color attachment operations. + // It is imporant to note, that the provided image handle is the same as the image array handle of the headset's entire framebuffer. + // When using the image handle directly, the provided subresource information should be used to select the correct layer. virtual lava::image::ptr get_framebuffer(FrameId frame_id) const = 0; + // Returns the image array which defines the entire framebuffer of the headset. + // The frame id can be used to access the layer in which the framebuffer of that id is stored. + // In case of a non-remote headset, the number of layers has to be two. + // Otherwise the the number of layers is equal to the maximum number of remote frame ids that was set by the active stereo strategy. + // The array image provided by the headset should support sampling, src and dest transfer operations as well as color attachment operations. + virtual lava::image::ptr get_framebuffer_array() const = 0; + // Returns the name of the headset. virtual const char* get_name() const = 0; diff --git a/src/headset/openvr_headset.cpp b/src/headset/openvr_headset.cpp index 3b0a4b79c17d08f4d0408425ba9e4a092742ab9c..5e4da384bcbda186fe9b619f14ddb892f7848154 100644 --- a/src/headset/openvr_headset.cpp +++ b/src/headset/openvr_headset.cpp @@ -57,12 +57,7 @@ bool OpenVRHeadset::on_create() this->compute_matrices(EYE_LEFT); this->compute_matrices(EYE_RIGHT); - if (!this->create_framebuffer(EYE_LEFT)) - { - return false; - } - - if (!this->create_framebuffer(EYE_RIGHT)) + if (!this->create_framebuffer()) { return false; } @@ -72,8 +67,7 @@ bool OpenVRHeadset::on_create() void OpenVRHeadset::on_destroy() { - this->destroy_framebuffer(EYE_LEFT); - this->destroy_framebuffer(EYE_RIGHT); + this->destroy_framebuffer(); vr::VR_Shutdown(); } @@ -142,7 +136,7 @@ void OpenVRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f lava::device_ptr device = this->get_application()->get_device(); - vr::VRVulkanTextureData_t texture_data; + vr::VRVulkanTextureArrayData_t texture_data; texture_data.m_nImage = (uint64_t)frame_image->get(); texture_data.m_pDevice = device->get(); texture_data.m_pPhysicalDevice = device->get_physical_device()->get(); @@ -153,13 +147,15 @@ void OpenVRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f texture_data.m_nHeight = this->resolution.y; texture_data.m_nFormat = this->get_format(); texture_data.m_nSampleCount = VK_SAMPLE_COUNT_1_BIT; + texture_data.m_unArrayIndex = frame_id; + texture_data.m_unArraySize = this->framebuffers.size(); vr::Texture_t texture; texture.handle = &texture_data; texture.eType = vr::TextureType_Vulkan; texture.eColorSpace = vr::ColorSpace_Auto; - vr::EVRCompositorError error = vr::VRCompositor()->Submit((vr::EVREye) frame_id, &texture); + vr::EVRCompositorError error = vr::VRCompositor()->Submit((vr::EVREye)frame_id, &texture, nullptr, vr::Submit_VulkanTextureWithArrayData); if (error != vr::VRCompositorError_None) { @@ -202,6 +198,11 @@ lava::image::ptr OpenVRHeadset::get_framebuffer(FrameId frame_id) const return this->framebuffers[frame_id]; } +lava::image::ptr OpenVRHeadset::get_framebuffer_array() const +{ + return this->framebuffer_array; +} + const char* OpenVRHeadset::get_name() const { return "OpenVR Headset"; @@ -212,25 +213,45 @@ bool OpenVRHeadset::is_attached(Controller controller) const return false; } -bool OpenVRHeadset::create_framebuffer(Eye eye) +bool OpenVRHeadset::create_framebuffer() { - lava::image::ptr framebuffer = lava::make_image(this->get_format()); - framebuffer->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + this->framebuffer_array = lava::make_image(this->get_format()); + this->framebuffer_array->set_layer_count(this->framebuffers.size()); + this->framebuffer_array->set_view_type(VK_IMAGE_VIEW_TYPE_2D_ARRAY); + this->framebuffer_array->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); - if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) + if (!this->framebuffer_array->create(this->get_application()->get_device(), this->resolution)) { return false; } - this->framebuffers[eye] = framebuffer; + for (uint32_t index = 0; index < this->framebuffers.size(); index++) + { + lava::image::ptr framebuffer = lava::make_image(this->get_format(), this->framebuffer_array->get()); + framebuffer->set_base_array_layer(index); + framebuffer->set_view_type(VK_IMAGE_VIEW_TYPE_2D); + + if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) + { + return false; + } + + this->framebuffers[index] = framebuffer; + } return true; } -void OpenVRHeadset::destroy_framebuffer(Eye eye) +void OpenVRHeadset::destroy_framebuffer() { - this->framebuffers[eye]->destroy(); - this->framebuffers[eye] = nullptr; + for (lava::image::ptr& framebuffer : this->framebuffers) + { + framebuffer->destroy(true); + framebuffer = nullptr; + } + + this->framebuffer_array->destroy(); + this->framebuffer_array = nullptr; } void OpenVRHeadset::compute_matrices(Eye eye) diff --git a/src/headset/openvr_headset.hpp b/src/headset/openvr_headset.hpp index 9b06fe7513f13f2f971045af6c3c226b202ae59d..42e1f4771c32f9f10f39872aa32d00cedceb93ca 100644 --- a/src/headset/openvr_headset.hpp +++ b/src/headset/openvr_headset.hpp @@ -36,14 +36,15 @@ public: const glm::mat4& get_controller_matrix(Controller controller) const override; lava::image::ptr get_framebuffer(FrameId frame_id) const override; + lava::image::ptr get_framebuffer_array() const override; const char* get_name() const override; bool is_attached(Controller controller) const override; private: - bool create_framebuffer(Eye eye); - void destroy_framebuffer(Eye eye); + bool create_framebuffer(); + void destroy_framebuffer(); void compute_matrices(Eye eye); @@ -58,6 +59,7 @@ private: std::array<glm::mat4, 2> projection_matrices; std::array<glm::mat4, 2> controller_matrices; std::array<lava::image::ptr, 2> framebuffers; + lava::image::ptr framebuffer_array; float near_plane = 0.1f; float far_plane = 1000.0f; diff --git a/src/headset/openxr_headset.cpp b/src/headset/openxr_headset.cpp index e38ef3ca3049d034d20ae6e3d47e951131d59568..a5b263aec215ed2eafdf60dece88b3c5cdb6086c 100644 --- a/src/headset/openxr_headset.cpp +++ b/src/headset/openxr_headset.cpp @@ -345,10 +345,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, image_barriers.size(), image_barriers.data()); VkImageCopy copy_region; - copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy_region.srcSubresource.mipLevel = 0; - copy_region.srcSubresource.baseArrayLayer = 0; - copy_region.srcSubresource.layerCount = 1; + copy_region.srcSubresource = frame_image->get_subresource_layers(), copy_region.srcOffset.x = 0; copy_region.srcOffset.y = 0; copy_region.srcOffset.z = 0; @@ -422,6 +419,11 @@ lava::image::ptr OpenXRHeadset::get_framebuffer(FrameId frame_id) const return this->framebuffers[frame_id]; } +lava::image::ptr OpenXRHeadset::get_framebuffer_array() const +{ + return this->framebuffer_array; +} + const char* OpenXRHeadset::get_name() const { return "OpenXR Headset"; @@ -434,10 +436,23 @@ bool OpenXRHeadset::is_attached(Controller controller) const bool OpenXRHeadset::create_framebuffers() { + this->framebuffer_array = lava::make_image(this->get_format()); + this->framebuffer_array->set_layer_count(this->framebuffers.size()); + this->framebuffer_array->set_view_type(VK_IMAGE_VIEW_TYPE_2D_ARRAY); + this->framebuffer_array->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + + if (!this->framebuffer_array->create(this->get_application()->get_device(), this->resolution)) + { + lava::log()->error("OpenXR: Can't create framebuffer array!"); + + return false; + } + for (uint32_t index = 0; index < this->framebuffers.size(); index++) { - lava::image::ptr framebuffer = lava::make_image(this->get_format()); - framebuffer->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + lava::image::ptr framebuffer = lava::make_image(this->get_format(), this->framebuffer_array->get()); + framebuffer->set_base_array_layer(index); + framebuffer->set_view_type(VK_IMAGE_VIEW_TYPE_2D); if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) { @@ -454,10 +469,14 @@ bool OpenXRHeadset::create_framebuffers() void OpenXRHeadset::destroy_framebuffers() { - for (uint32_t index = 0; index < this->framebuffers.size(); index++) + for (lava::image::ptr& framebuffer : this->framebuffers) { - this->framebuffers[index]->destroy(); + framebuffer->destroy(true); + framebuffer = nullptr; } + + this->framebuffer_array->destroy(); + this->framebuffer_array = nullptr; } bool OpenXRHeadset::create_swapchains() diff --git a/src/headset/openxr_headset.hpp b/src/headset/openxr_headset.hpp index 0ac0836cd96cbaa3bc05e567b6dce03dfb14a777..f0adbde8cbcd03eacfb17d487a15ac8b81816f3f 100644 --- a/src/headset/openxr_headset.hpp +++ b/src/headset/openxr_headset.hpp @@ -36,6 +36,7 @@ public: const glm::mat4& get_controller_matrix(Controller controller) const override; lava::image::ptr get_framebuffer(FrameId frame_id) const override; + lava::image::ptr get_framebuffer_array() const override; const char* get_name() const override; @@ -78,6 +79,7 @@ private: std::array<uint32_t, 2> swapchain_indices; std::array<std::vector<VkImage>, 2> swapchain_images; std::array<lava::image::ptr, 2> framebuffers; + lava::image::ptr framebuffer_array; std::vector<std::string> instance_extensions; std::vector<std::string> device_extensions; diff --git a/src/headset/remote_headset.cpp b/src/headset/remote_headset.cpp index bfb0399955f7b6892d4907d254b2a2ad2a811ff6..00c9c0059dcffcc70253fbfe1f9e594de696c385 100644 --- a/src/headset/remote_headset.cpp +++ b/src/headset/remote_headset.cpp @@ -263,6 +263,11 @@ lava::image::ptr RemoteHeadset::get_framebuffer(FrameId frame_id) const return this->framebuffers[frame_id]; } +lava::image::ptr RemoteHeadset::get_framebuffer_array() const +{ + return this->framebuffer_array; +} + const char* RemoteHeadset::get_name() const { return "Remote Headset"; @@ -321,32 +326,46 @@ void RemoteHeadset::destroy_server() bool RemoteHeadset::create_framebuffers() { - this->framebuffers.resize(this->frame_id_count); + this->framebuffers.resize(this->frame_id_count); - for (uint32_t index = 0; index < this->framebuffers.size(); index++) - { - lava::image::ptr framebuffer = lava::make_image(this->get_format()); - framebuffer->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + this->framebuffer_array = lava::make_image(this->get_format()); + this->framebuffer_array->set_layer_count(this->framebuffers.size()); + this->framebuffer_array->set_view_type(VK_IMAGE_VIEW_TYPE_2D_ARRAY); + this->framebuffer_array->set_usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + + if (!this->framebuffer_array->create(this->get_application()->get_device(), this->resolution)) + { + return false; + } + + for (uint32_t index = 0; index < this->framebuffers.size(); index++) + { + lava::image::ptr framebuffer = lava::make_image(this->get_format(), this->framebuffer_array->get()); + framebuffer->set_base_array_layer(index); + framebuffer->set_view_type(VK_IMAGE_VIEW_TYPE_2D); if (!framebuffer->create(this->get_application()->get_device(), this->resolution)) - { + { return false; } this->framebuffers[index] = framebuffer; - } - + } + return true; } void RemoteHeadset::destroy_framebuffers() { - for (uint32_t index = 0; index < this->framebuffers.size(); index++) - { - this->framebuffers[index]->destroy(); - } + for (lava::image::ptr& framebuffer : this->framebuffers) + { + framebuffer->destroy(true); + } + + this->framebuffers.clear(); - this->framebuffers.clear(); + this->framebuffer_array->destroy(); + this->framebuffer_array = nullptr; } bool RemoteHeadset::create_encoders() diff --git a/src/headset/remote_headset.hpp b/src/headset/remote_headset.hpp index d6ba198e7764e9f1f1ab53eb1acbab840df70a14..c59898fbea6d3a4b651cf185e8f2597bc7074edf 100644 --- a/src/headset/remote_headset.hpp +++ b/src/headset/remote_headset.hpp @@ -53,6 +53,7 @@ public: const glm::mat4& get_controller_matrix(Controller controller) const override; lava::image::ptr get_framebuffer(FrameId frame_id) const override; + lava::image::ptr get_framebuffer_array() const override; const char* get_name() const override; @@ -138,6 +139,7 @@ private: uint32_t encoder_frame_rate = 90; uint32_t encoder_quality = 35; + lava::image::ptr framebuffer_array; std::vector<lava::image::ptr> framebuffers; std::vector<Encoder::Ptr> encoders; diff --git a/src/strategy/depth_peeling_reprojection_stereo.cpp b/src/strategy/depth_peeling_reprojection_stereo.cpp index bf71459f84e2747414b8b0209fc7103a45b06203..fd33386f6c7d5d85684c546bb5640cd8529fb9f1 100644 --- a/src/strategy/depth_peeling_reprojection_stereo.cpp +++ b/src/strategy/depth_peeling_reprojection_stereo.cpp @@ -52,22 +52,16 @@ bool DepthPeelingReprojectionStereo::on_render(VkCommandBuffer command_buffer, l { this->write_buffer(frame); - VkImageSubresourceRange const image_range{ - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .levelCount = 1, - .layerCount = 1, - }; - insert_image_memory_barrier(get_device(), command_buffer, this->get_headset()->get_framebuffer(EYE_LEFT)->get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - image_range); + this->get_headset()->get_framebuffer(EYE_LEFT)->get_subresource_range()); insert_image_memory_barrier(get_device(), command_buffer, this->get_headset()->get_framebuffer(EYE_RIGHT)->get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - image_range); + this->get_headset()->get_framebuffer(EYE_LEFT)->get_subresource_range()); this->get_headset()->submit_metadata(FrameMetadata()); @@ -313,12 +307,7 @@ void DepthPeelingReprojectionStereo::render_companion_window(VkCommandBuffer com .y = 0, .z = 0, }, - .dstSubresource = VkImageSubresourceLayers { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }, + .dstSubresource = get_headset()->get_framebuffer(EYE_LEFT)->get_subresource_layers(), .dstOffset = VkOffset3D { .x = 0, .y = 0, @@ -378,7 +367,7 @@ void DepthPeelingReprojectionStereo::render_companion_window(VkCommandBuffer com VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - image_range); + get_headset()->get_framebuffer(EYE_LEFT)->get_subresource_range()); // insert_image_memory_barrier(app()->device(), command_buffer, app()->right_eye_framebuffer()->color_image->get(), // VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, diff --git a/src/strategy/multi_view_stereo.cpp b/src/strategy/multi_view_stereo.cpp index aa2b1d2583499b93e8c773c63db83cf944623e25..577df49f78eb119abfaa3ce89249f3d9fec7470b 100644 --- a/src/strategy/multi_view_stereo.cpp +++ b/src/strategy/multi_view_stereo.cpp @@ -56,11 +56,6 @@ void MultiViewStereo::on_destroy() this->render_pass->destroy(); } - if (this->color_buffer != nullptr) - { - this->color_buffer->destroy(); - } - if (this->depth_buffer != nullptr) { this->depth_buffer->destroy(); @@ -85,110 +80,13 @@ bool MultiViewStereo::on_render(VkCommandBuffer command_buffer, lava::index fram this->render_pass->process(command_buffer, 0); this->get_pass_timer()->end_pass(command_buffer); - VkImageMemoryBarrier left_barrier; - left_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - left_barrier.pNext = nullptr; - left_barrier.srcAccessMask = 0; - left_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - left_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - left_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - left_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - left_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - left_barrier.image = this->get_headset()->get_framebuffer(EYE_LEFT)->get(); - left_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - left_barrier.subresourceRange.baseMipLevel = 0; - left_barrier.subresourceRange.levelCount = 1; - left_barrier.subresourceRange.baseArrayLayer = 0; - left_barrier.subresourceRange.layerCount = 1; - - VkImageMemoryBarrier right_barrier; - right_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - right_barrier.pNext = nullptr; - right_barrier.srcAccessMask = 0; - right_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - right_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - right_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - right_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - right_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - right_barrier.image = this->get_headset()->get_framebuffer(EYE_RIGHT)->get(); - right_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - right_barrier.subresourceRange.baseMipLevel = 0; - right_barrier.subresourceRange.levelCount = 1; - right_barrier.subresourceRange.baseArrayLayer = 0; - right_barrier.subresourceRange.layerCount = 1; - - std::array<VkImageMemoryBarrier, 2> begin_barriers = - { - left_barrier, - right_barrier - }; - - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, begin_barriers.size(), begin_barriers.data()); - - VkImageSubresourceLayers subresource; - subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresource.mipLevel = 0; - subresource.baseArrayLayer = 0; - subresource.layerCount = 1; - - VkOffset3D offset; - offset.x = 0; - offset.y = 0; - offset.z = 0; - - VkExtent3D extent; - extent.width = this->get_headset()->get_resolution().x; - extent.height = this->get_headset()->get_resolution().y; - extent.depth = 1; - - VkImageCopy left_copy; - left_copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - left_copy.srcSubresource.mipLevel = 0; - left_copy.srcSubresource.baseArrayLayer = 0; - left_copy.srcSubresource.layerCount = 1; - left_copy.srcOffset = offset; - left_copy.dstSubresource = subresource; - left_copy.dstOffset = offset; - left_copy.extent = extent; - - VkImageCopy right_copy; - right_copy.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - right_copy.srcSubresource.mipLevel = 0; - right_copy.srcSubresource.baseArrayLayer = 1; - right_copy.srcSubresource.layerCount = 1; - right_copy.srcOffset = offset; - right_copy.dstSubresource = subresource; - right_copy.dstOffset = offset; - right_copy.extent = extent; - - vkCmdCopyImage(command_buffer, this->color_buffer->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, this->get_headset()->get_framebuffer(EYE_LEFT)->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &left_copy); - vkCmdCopyImage(command_buffer, this->color_buffer->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, this->get_headset()->get_framebuffer(EYE_RIGHT)->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &right_copy); - - left_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - left_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - left_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - left_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - - right_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - right_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - right_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - right_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - - std::array<VkImageMemoryBarrier, 2> end_barriers = - { - left_barrier, - right_barrier - }; - - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, end_barriers.size(), end_barriers.data()); - - this->get_frame_capture()->capture_image(command_buffer, this->get_headset()->get_framebuffer(EYE_LEFT), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "left_eye"); - this->get_companion_window()->submit_image(command_buffer, EYE_LEFT, this->get_headset()->get_framebuffer(EYE_LEFT), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - this->get_headset()->submit_frame(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, EYE_LEFT); + this->get_frame_capture()->capture_image(command_buffer, this->get_headset()->get_framebuffer(EYE_LEFT), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "left_eye"); + this->get_companion_window()->submit_image(command_buffer, EYE_LEFT, this->get_headset()->get_framebuffer(EYE_LEFT), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + this->get_headset()->submit_frame(command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, EYE_LEFT); - this->get_frame_capture()->capture_image(command_buffer, this->get_headset()->get_framebuffer(EYE_RIGHT), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "right_eye"); - this->get_companion_window()->submit_image(command_buffer, EYE_RIGHT, this->get_headset()->get_framebuffer(EYE_RIGHT), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - this->get_headset()->submit_frame(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, EYE_RIGHT); + this->get_frame_capture()->capture_image(command_buffer, this->get_headset()->get_framebuffer(EYE_RIGHT), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "right_eye"); + this->get_companion_window()->submit_image(command_buffer, EYE_RIGHT, this->get_headset()->get_framebuffer(EYE_RIGHT), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + this->get_headset()->submit_frame(command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, EYE_RIGHT); return true; } @@ -239,19 +137,6 @@ bool MultiViewStereo::create_render_pass() return false; } - this->color_buffer = lava::make_image(this->get_headset()->get_format()); - this->color_buffer->set_usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); - this->color_buffer->set_tiling(VK_IMAGE_TILING_OPTIMAL); - this->color_buffer->set_view_type(VK_IMAGE_VIEW_TYPE_2D_ARRAY); - this->color_buffer->set_layer_count(2); - - if (!this->color_buffer->create(this->get_device(), this->get_headset()->get_resolution())) - { - lava::log()->error("Can't create layered color buffer for multi-view stereo!"); - - return false; - } - this->depth_attachment = lava::make_attachment(VK_FORMAT_D32_SFLOAT); this->depth_attachment->set_op(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); this->depth_attachment->set_stencil_op(VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE); @@ -260,7 +145,7 @@ bool MultiViewStereo::create_render_pass() this->color_attachment = lava::make_attachment(this->get_headset()->get_format()); this->color_attachment->set_op(VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE); this->color_attachment->set_stencil_op(VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE); - this->color_attachment->set_layouts(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + this->color_attachment->set_layouts(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VkClearValue depth_clear_value; depth_clear_value.depthStencil.depth = 1.0f; @@ -310,7 +195,7 @@ bool MultiViewStereo::create_render_pass() lava::VkImageViews framebuffer_views = { this->depth_buffer->get_view(), - this->color_buffer->get_view() + this->get_headset()->get_framebuffer_array()->get_view() }; uint32_t view_mask = 0x03; //NOTE: First and second bit set, meaning that the first and second layer of the framebuffer will be modified. diff --git a/src/strategy/multi_view_stereo.hpp b/src/strategy/multi_view_stereo.hpp index 81e53c6194532f1cee97699903154bcdc30cee71..6c91be3a903afa644dcee3956a70fad3fcc5e3d6 100644 --- a/src/strategy/multi_view_stereo.hpp +++ b/src/strategy/multi_view_stereo.hpp @@ -40,9 +40,8 @@ private: lava::graphics_pipeline::ptr pipeline; lava::render_pass::ptr render_pass; - lava::attachment::ptr depth_attachment; lava::attachment::ptr color_attachment; - lava::image::ptr color_buffer; + lava::attachment::ptr depth_attachment; lava::image::ptr depth_buffer; }; diff --git a/src/utility/companion_window.cpp b/src/utility/companion_window.cpp index 86ab73a926f1df4eb155f5126f3958b4b4e82e32..078a674517246c398ed988f821d7e381927293cd 100644 --- a/src/utility/companion_window.cpp +++ b/src/utility/companion_window.cpp @@ -146,7 +146,7 @@ void CompanionWindow::submit_image(VkCommandBuffer command_buffer, Eye eye, lava } VkImageBlit image_blit; - image_blit.srcSubresource = subresource_layers; + image_blit.srcSubresource = image->get_subresource_layers(); image_blit.srcOffsets[0].x = 0; image_blit.srcOffsets[0].y = 0; image_blit.srcOffsets[0].z = 0; diff --git a/src/utility/frame_capture.cpp b/src/utility/frame_capture.cpp index 08233f1858d773b3336a43c4131c8f20ac22c3f7..5c8680b53d5229de33baf8bb6c51bb8c69468748 100644 --- a/src/utility/frame_capture.cpp +++ b/src/utility/frame_capture.cpp @@ -60,19 +60,6 @@ void FrameCapture::capture_image(VkCommandBuffer command_buffer, lava::image::pt image_extend.height = image_size.y; image_extend.depth = 1; - VkImageSubresourceRange image_subresource_range; - image_subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_subresource_range.baseArrayLayer = 0; - image_subresource_range.baseMipLevel = 0; - image_subresource_range.layerCount = 1; - image_subresource_range.levelCount = 1; - - VkImageSubresourceLayers image_subresource_layers; - image_subresource_layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_subresource_layers.baseArrayLayer = 0; - image_subresource_layers.layerCount = 1; - image_subresource_layers.mipLevel = 0; - VkImageMemoryBarrier begin_barrier; begin_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; begin_barrier.pNext = nullptr; @@ -83,7 +70,7 @@ void FrameCapture::capture_image(VkCommandBuffer command_buffer, lava::image::pt begin_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; begin_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; begin_barrier.image = image->get(); - begin_barrier.subresourceRange = image_subresource_range; + begin_barrier.subresourceRange = image->get_subresource_range(); vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &begin_barrier); @@ -91,7 +78,7 @@ void FrameCapture::capture_image(VkCommandBuffer command_buffer, lava::image::pt region.bufferOffset = 0; region.bufferRowLength = 0; //Tightly packed region.bufferImageHeight = 0; - region.imageSubresource = image_subresource_layers; + region.imageSubresource = image->get_subresource_layers(); region.imageOffset = image_offset; region.imageExtent = image_extend; @@ -107,7 +94,7 @@ void FrameCapture::capture_image(VkCommandBuffer command_buffer, lava::image::pt end_image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; end_image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; end_image_barrier.image = image->get(); - end_image_barrier.subresourceRange = image_subresource_range; + end_image_barrier.subresourceRange = image->get_subresource_range(); VkBufferMemoryBarrier end_buffer_barrier; end_buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;