]> git.tdb.fi Git - libs/gl.git/commitdiff
Use another callback for pre-transfer synchronization
authorMikko Rasa <tdb@tdb.fi>
Tue, 30 Nov 2021 22:17:53 +0000 (00:17 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 30 Nov 2021 22:23:38 +0000 (00:23 +0200)
source/backends/vulkan/buffer_backend.cpp
source/backends/vulkan/texture1d_backend.cpp
source/backends/vulkan/texture2d_backend.cpp
source/backends/vulkan/texture3d_backend.cpp
source/backends/vulkan/texturecube_backend.cpp
source/backends/vulkan/transferqueue.cpp
source/backends/vulkan/transferqueue.h

index 9290b42aefe2fff301735eaabf0684f4f7b2f327..14164daf208a8b67f4fdba00284b10df2d2aedc3 100644 (file)
@@ -52,17 +52,19 @@ void VulkanBuffer::allocate()
 
 void VulkanBuffer::sub_data(size_t off, size_t sz, const void *d)
 {
-       device.get_synchronizer().write_buffer(handle, off, sz);
-
-       void *staging = device.get_transfer_queue().prepare_transfer(sz, [this, off, sz](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
-               const VulkanFunctions &vk = device.get_functions();
-
-               VkBufferCopy region = { };
-               region.srcOffset = src_off;
-               region.dstOffset = off;
-               region.size = sz;
-               vk.CmdCopyBuffer(cmd_buf, staging_buf, handle, 1, &region);
-       });
+       void *staging = device.get_transfer_queue().prepare_transfer(sz,
+               [this, off, sz](){
+                       device.get_synchronizer().write_buffer(handle, off, sz);
+               },
+               [this, off, sz](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
+                       const VulkanFunctions &vk = device.get_functions();
+
+                       VkBufferCopy region = { };
+                       region.srcOffset = src_off;
+                       region.dstOffset = off;
+                       region.size = sz;
+                       vk.CmdCopyBuffer(cmd_buf, staging_buf, handle, 1, &region);
+               });
 
        const char *src = static_cast<const char *>(d);
        copy(src, src+sz, static_cast<char *>(staging));
index 91c6252a85d1544597f7a273e3e7e40a0fa8a381..d97576ce0990e0170c433c8356ad3df6ab1d3a69 100644 (file)
@@ -27,10 +27,14 @@ void VulkanTexture1D::sub_image(unsigned level, int x, unsigned wd, const void *
        const Texture1D &self = *static_cast<const Texture1D *>(this);
 
        unsigned level_size = self.get_level_size(level);
-       change_layout(self.levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (x==0 && wd==level_size));
+       bool discard = (x==0 && wd==level_size);
 
        size_t data_size = wd*get_pixel_size(storage_fmt);
        void *staging = device.get_transfer_queue().prepare_transfer(data_size,
+               [this, level, discard](){
+                       unsigned n_levels = static_cast<const Texture1D *>(this)->levels;
+                       change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard);
+               },
                [this, level, x, wd](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
                        const VulkanFunctions &vk = device.get_functions();
 
index d3db86d3ae27efe214ec2acd6586e96350ad4599..e568d14f75843ea7ae57e6a6bbb520a777ed5712 100644 (file)
@@ -28,10 +28,14 @@ void VulkanTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsig
        const Texture2D &self = *static_cast<const Texture2D *>(this);
 
        auto level_size = self.get_level_size(level);
-       change_layout(self.levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (x==0 && y==0 && wd==level_size.x && ht==level_size.y));
+       bool discard = (x==0 && y==0 && wd==level_size.x && ht==level_size.y);
 
        size_t data_size = wd*ht*get_pixel_size(storage_fmt);
        void *staging = device.get_transfer_queue().prepare_transfer(data_size,
+               [this, level, discard](){
+                       unsigned n_levels = static_cast<const Texture2D *>(this)->levels;
+                       change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard);
+               },
                [this, level, x, y, wd, ht](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
                        const VulkanFunctions &vk = device.get_functions();
 
index 03a957344e11083fb0bfdcb0ac8e2eb051aa28a7..4c9873d9dfaaebb912fd243a26efa80ec564e743 100644 (file)
@@ -34,10 +34,13 @@ void VulkanTexture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd
 
        auto level_size = self.get_level_size(level);
        bool discard = (x==0 && y==0 && z==0 && wd==level_size.x && ht==level_size.y && dp==level_size.z);
-       change_layout(self.levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard);
 
        size_t data_size = wd*ht*dp*get_pixel_size(storage_fmt);
        void *staging = device.get_transfer_queue().prepare_transfer(data_size,
+               [this, level, discard](){
+                       unsigned n_levels = static_cast<const Texture3D *>(this)->levels;
+                       change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard);
+               },
                [this, level, x, y, z, wd, ht, dp](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
                        const VulkanFunctions &vk = device.get_functions();
 
index 38348f34b8636abd0b09e0e3c478fd694abccaea..f421e20d68be259dc110eb20820a3867f4fa5e31 100644 (file)
@@ -30,10 +30,14 @@ void VulkanTextureCube::sub_image(unsigned face, unsigned level, int x, int y, u
        const TextureCube &self = *static_cast<const TextureCube *>(this);
 
        unsigned level_size = self.get_level_size(level);
-       change_layout(self.levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (x==0 && y==0 && wd==level_size && ht==level_size));
+       bool discard = (x==0 && y==0 && wd==level_size && ht==level_size);
 
        size_t data_size = wd*ht*get_pixel_size(storage_fmt);
        void *staging = device.get_transfer_queue().prepare_transfer(data_size,
+               [this, level, discard](){
+                       unsigned n_levels = static_cast<const TextureCube *>(this)->levels;
+                       change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard);
+               },
                [this, face, level, x, y, wd, ht](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){
                        const VulkanFunctions &vk = device.get_functions();
 
index d0ccb0d571c88419838faec234a7cd99e0f7fcd9..7f1cfa914884a518a7c766abe385204f72766e66 100644 (file)
@@ -34,13 +34,18 @@ TransferQueue::PendingTransfer &TransferQueue::prepare_transfer(size_t size)
 
 void TransferQueue::dispatch_transfers(VkCommandBuffer command_buffer)
 {
-       if(!transfers.empty())
-               device.get_synchronizer().barrier(command_buffer);
+       if(transfers.empty())
+               return;
+
+       for(const PendingTransfer &t: transfers)
+               t.synchronize();
+
+       device.get_synchronizer().barrier(command_buffer);
 
        for(const PendingTransfer &t: transfers)
        {
                VkBuffer buffer = buffers[t.buffer_index].buffer;
-               t.callback(command_buffer, buffer, t.offset);
+               t.transfer(command_buffer, buffer, t.offset);
        }
 
        transfers.clear();
index 419760bdf4d6b709bd4b28a393428f8da45f9383..a25519c8a121b417b0fe1dc1a60692bc7f7f90ff 100644 (file)
@@ -28,14 +28,13 @@ private:
                ~StagingBuffer();
        };
 
-       using TransferCallback = void(VkCommandBuffer, VkBuffer, std::size_t);
-
        struct PendingTransfer
        {
                unsigned buffer_index = 0;
                std::size_t offset = 0;
                std::size_t size = 0;
-               std::function<TransferCallback> callback;
+               std::function<void()> synchronize;
+               std::function<void(VkCommandBuffer, VkBuffer, std::size_t)> transfer;
        };
 
        Device &device;
@@ -46,8 +45,8 @@ private:
 public:
        TransferQueue(Device &);
 
-       template<typename T>
-       void *prepare_transfer(std::size_t, T &&);
+       template<typename S, typename T>
+       void *prepare_transfer(std::size_t, S &&, T &&);
 
 private:
        PendingTransfer &prepare_transfer(std::size_t);
@@ -56,11 +55,12 @@ public:
        void dispatch_transfers(VkCommandBuffer);
 };
 
-template<typename T>
-void *TransferQueue::prepare_transfer(std::size_t size, T &&callback)
+template<typename S, typename T>
+void *TransferQueue::prepare_transfer(std::size_t size, S &&synchronize, T &&transfer)
 {
        PendingTransfer &pt = prepare_transfer(size);
-       pt.callback = std::forward<T>(callback);
+       pt.synchronize = std::forward<S>(synchronize);
+       pt.transfer = std::forward<T>(transfer);
        return static_cast<char *>(buffers[pt.buffer_index].mapped_address)+pt.offset;
 }