|
1 | 1 | #include "le_core.h" |
2 | 2 | #include "le_backend_vk.h" |
3 | 3 | #include "le_log.h" |
| 4 | +#include "private/le_backend_vk/le_command_stream_t.h" |
4 | 5 | #include "util/vk_mem_alloc/vk_mem_alloc.h" // for allocation |
5 | 6 | #include "le_backend_types_internal.h" // includes vulkan.hpp |
6 | 7 | #include "le_swapchain_vk.h" |
@@ -612,6 +613,8 @@ struct BackendFrameData { |
612 | 613 |
|
613 | 614 | le_staging_allocator_o* stagingAllocator; // owning: allocator for large objects to GPU memory |
614 | 615 |
|
| 616 | + std::vector<le_command_stream_t*> command_streams; // owning; these must be destroyed when frame gets destroyed. |
| 617 | + |
615 | 618 | bool must_create_queues_dot_graph = false; |
616 | 619 | }; |
617 | 620 |
|
@@ -830,28 +833,36 @@ static void backend_destroy( le_backend_o* self ) { |
830 | 833 |
|
831 | 834 | vmaDestroyPool( self->mAllocator, frameData.allocationPool ); |
832 | 835 |
|
833 | | - // destroy staging allocator |
| 836 | + // Destroy staging allocator |
834 | 837 | le_staging_allocator_i.destroy( frameData.stagingAllocator ); |
835 | 838 |
|
836 | | - // remove any binned resources |
837 | | - for ( auto& a : frameData.binnedResources ) { |
| 839 | + { // Remove any binned resources |
| 840 | + for ( auto& a : frameData.binnedResources ) { |
838 | 841 |
|
839 | | - if ( a.second.info.isBuffer() ) { |
840 | | - vkDestroyBuffer( device, a.second.as.buffer, nullptr ); |
841 | | - } else { |
842 | | - vkDestroyImage( device, a.second.as.image, nullptr ); |
843 | | - } |
844 | | - if ( a.second.info.isBlas() ) { |
845 | | - vkDestroyBuffer( device, a.second.info.blasInfo.buffer, nullptr ); |
846 | | - vkDestroyAccelerationStructureKHR( device, a.second.as.blas, nullptr ); |
| 842 | + if ( a.second.info.isBuffer() ) { |
| 843 | + vkDestroyBuffer( device, a.second.as.buffer, nullptr ); |
| 844 | + } else { |
| 845 | + vkDestroyImage( device, a.second.as.image, nullptr ); |
| 846 | + } |
| 847 | + if ( a.second.info.isBlas() ) { |
| 848 | + vkDestroyBuffer( device, a.second.info.blasInfo.buffer, nullptr ); |
| 849 | + vkDestroyAccelerationStructureKHR( device, a.second.as.blas, nullptr ); |
| 850 | + } |
| 851 | + if ( a.second.info.isTlas() ) { |
| 852 | + vkDestroyBuffer( device, a.second.info.tlasInfo.buffer, nullptr ); |
| 853 | + vkDestroyAccelerationStructureKHR( device, a.second.as.tlas, nullptr ); |
| 854 | + } |
| 855 | + vmaFreeMemory( self->mAllocator, a.second.allocation ); |
847 | 856 | } |
848 | | - if ( a.second.info.isTlas() ) { |
849 | | - vkDestroyBuffer( device, a.second.info.tlasInfo.buffer, nullptr ); |
850 | | - vkDestroyAccelerationStructureKHR( device, a.second.as.tlas, nullptr ); |
| 857 | + frameData.binnedResources.clear(); |
| 858 | + } |
| 859 | + |
| 860 | + { // Clear command streams |
| 861 | + for ( auto& cs : frameData.command_streams ) { |
| 862 | + delete ( cs ); |
851 | 863 | } |
852 | | - vmaFreeMemory( self->mAllocator, a.second.allocation ); |
| 864 | + frameData.command_streams.clear(); |
853 | 865 | } |
854 | | - frameData.binnedResources.clear(); |
855 | 866 | } |
856 | 867 |
|
857 | 868 | self->mFrames.clear(); |
@@ -2105,6 +2116,11 @@ static bool backend_clear_frame( le_backend_o* self, size_t frameIndex ) { |
2105 | 2116 | } |
2106 | 2117 | frame.passes.clear(); |
2107 | 2118 |
|
| 2119 | + // Reset command streams |
| 2120 | + for ( auto cs : frame.command_streams ) { |
| 2121 | + cs->reset(); |
| 2122 | + } |
| 2123 | + |
2108 | 2124 | frame.frameNumber = self->mFramesCount++; // note post-increment |
2109 | 2125 |
|
2110 | 2126 | return true; |
@@ -4237,6 +4253,23 @@ static le_allocator_o** backend_get_transient_allocators( le_backend_o* self, si |
4237 | 4253 | return self->mFrames[ frameIndex ].allocators.data(); |
4238 | 4254 | } |
4239 | 4255 |
|
| 4256 | +// ---------------------------------------------------------------------- |
| 4257 | + |
| 4258 | +static le_command_stream_t** backend_get_frame_command_streams( le_backend_o* self, size_t frameIndex, size_t num_command_streams ) { |
| 4259 | + |
| 4260 | + // Check if the command stream pool has enough free command stream elements in the pool for us |
| 4261 | + // If no, we must add some additional command streams |
| 4262 | + |
| 4263 | + auto& cmd_streams = self->mFrames[ frameIndex ].command_streams; |
| 4264 | + |
| 4265 | + // We should maybe find a nicer way to do this... |
| 4266 | + while ( cmd_streams.size() < num_command_streams ) { |
| 4267 | + cmd_streams.insert( cmd_streams.end(), new le_command_stream_t() ); |
| 4268 | + } |
| 4269 | + |
| 4270 | + return cmd_streams.data(); |
| 4271 | +}; |
| 4272 | + |
4240 | 4273 | // ---------------------------------------------------------------------- |
4241 | 4274 | static le_allocator_o** backend_create_transient_allocators( le_backend_o* self, size_t frameIndex, size_t numAllocators ) { |
4242 | 4275 |
|
@@ -7803,6 +7836,7 @@ LE_MODULE_REGISTER_IMPL( le_backend_vk, api_ ) { |
7803 | 7836 | vk_backend_i.get_data_frames_count = backend_get_data_frames_count; |
7804 | 7837 | vk_backend_i.get_transient_allocators = backend_get_transient_allocators; |
7805 | 7838 | vk_backend_i.get_staging_allocator = backend_get_staging_allocator; |
| 7839 | + vk_backend_i.get_frame_command_streams = backend_get_frame_command_streams; |
7806 | 7840 | vk_backend_i.poll_frame_fence = backend_poll_frame_fence; |
7807 | 7841 | vk_backend_i.clear_frame = backend_clear_frame; |
7808 | 7842 | vk_backend_i.acquire_physical_resources = backend_acquire_physical_resources; |
|
0 commit comments