Don't remove individual mipmap levels from Synchronizer master
authorMikko Rasa <tdb@tdb.fi>
Thu, 9 Dec 2021 13:23:21 +0000 (15:23 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 9 Dec 2021 13:23:21 +0000 (15:23 +0200)
Keep them around until all levels have been transitioned to shader read
only optimal, to ensure that changing the layout of a split image as a
whole works correctly.

source/backends/vulkan/synchronizer.cpp

index 3ec04026a09ae2e2617c3461e4a746544f0ab119..93f48b847f9290cc456d06fe4d108bea1068bf2b 100644 (file)
@@ -212,29 +212,28 @@ void Synchronizer::barrier(VkCommandBuffer command_buffer)
                }
        }
 
-       bool sparse_levels = false;
        for(auto i=image_accesses.begin(); i!=image_accesses.end(); )
        {
-               if(i->level==-2)
-               {
-                       sparse_levels = true;
-                       ++i;
-               }
-               else if(i->pending_layout==VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+               if(i->level!=-1)
                {
-                       VkImage image = i->image;
-                       i = image_accesses.erase(i);
-                       if(i->image!=image)
+                       auto j = i;
+                       if(j->level==-2)
+                               ++j;
+
+                       bool remove_image = true;
+                       for(; (j!=image_accesses.end() && j->image==i->image); ++j)
+                               remove_image &= (j->pending_layout==VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+
+                       if(remove_image)
+                               i = image_accesses.erase(i, j);
+                       else
                        {
-                               if(sparse_levels)
-                               {
-                                       auto j = prev(i);
-                                       if(j->level==-2)
-                                               i = image_accesses.erase(j);
-                               }
-                               sparse_levels = false;
+                               for(; i!=j; ++i)
+                                       i->current_layout = i->pending_layout;
                        }
                }
+               else if(i->pending_layout==VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
+                       i = image_accesses.erase(i);
                else
                {
                        i->current_layout = i->pending_layout;