Bladeren bron

vulkan: Fix issues with texture barriers not being flushed properly

rdb 4 dagen geleden
bovenliggende
commit
461e0a6a50

+ 2 - 0
panda/src/vulkandisplay/vulkanCommandBuffer.I

@@ -66,6 +66,7 @@ operator = (VulkanCommandBuffer &&from) noexcept {
 /**
  * Queues a low-level barrier.  Only use for images not managed by a
  * VulkanTextureContext, otherwise see the other overload.
+ * Note that this will not take effect until flush_barriers() is called.
  */
 INLINE void VulkanCommandBuffer::
 add_barrier(VkImageMemoryBarrier2 barrier) {
@@ -75,6 +76,7 @@ add_barrier(VkImageMemoryBarrier2 barrier) {
 /**
  * Queues a low-level barrier.  Only use for images not managed by a
  * VulkanBufferContext, otherwise see the other overload.
+ * Note that this will not take effect until flush_barriers() is called.
  */
 INLINE void VulkanCommandBuffer::
 add_barrier(VkBufferMemoryBarrier2 barrier) {

+ 7 - 1
panda/src/vulkandisplay/vulkanCommandBuffer.cxx

@@ -121,7 +121,13 @@ add_barrier(VulkanTextureContext *tc, VkImageLayout layout,
     const char src_type = (src_access_mask != 0) ? 'W' : 'R';
     auto &out = vulkandisplay_cat.spam()
       << (hoist_possible ? "Hoisting " : "Issuing ")
-      << dst_type << 'a' << src_type << " barrier for ";
+      << dst_type << 'a' << src_type;
+
+    if (layout != tc->_layout) {
+      out << " (layout " << tc->_layout << "->" << layout << ")";
+    }
+
+    out << " barrier for ";
 
     Texture *tex = tc->get_texture();
     if (tex != nullptr) {

+ 3 - 13
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.cxx

@@ -1749,7 +1749,6 @@ upload_texture(VulkanTextureContext *tc, CompletionToken token) {
     _transfer_cmd.add_barrier(tc, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                               VK_PIPELINE_STAGE_2_TRANSFER_BIT,
                               VK_ACCESS_2_TRANSFER_WRITE_BIT);
-    _transfer_cmd.flush_barriers();
 
     // Schedule a copy from our staging buffer to the image.
     VkBufferImageCopy region = {};
@@ -1784,17 +1783,6 @@ upload_texture(VulkanTextureContext *tc, CompletionToken token) {
     barrier.subresourceRange.baseArrayLayer = 0;
     barrier.subresourceRange.layerCount = tc->_array_layers;
 
-    VkDependencyInfo dep_info = {
-      VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
-      nullptr, // pNext
-      0, // dependencyFlags
-      0, // memoryBarrierCount
-      nullptr, // pMemoryBarriers
-      0, // bufferMemoryBarrierCount
-      nullptr, // pBufferMemoryBarriers
-      1, &barrier,
-    };
-
     SparseArray levels_in_dst_optimal_layout;
     levels_in_dst_optimal_layout.set_range(0, level_offsets.size());
 
@@ -1803,6 +1791,7 @@ upload_texture(VulkanTextureContext *tc, CompletionToken token) {
         // Schedule a copy from the staging buffer.
         region.bufferOffset = (uint32_t)offset;
 
+        _transfer_cmd.flush_barriers();
         vkCmdCopyBufferToImage(_transfer_cmd, buffer, image,
                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
 
@@ -1815,7 +1804,8 @@ upload_texture(VulkanTextureContext *tc, CompletionToken token) {
         // There's no image for this level, we are supposed to generate it.
         // Transition the previous mipmap level to optimal read layout.
         barrier.subresourceRange.baseMipLevel = blit.srcSubresource.mipLevel;
-        vkCmdPipelineBarrier2(_transfer_cmd, &dep_info);
+        _transfer_cmd.add_barrier(barrier);
+        _transfer_cmd.flush_barriers();
         levels_in_dst_optimal_layout.clear_bit(barrier.subresourceRange.baseMipLevel);
 
         blit.dstSubresource.mipLevel = region.imageSubresource.mipLevel;

+ 2 - 0
panda/src/vulkandisplay/vulkanTextureContext.cxx

@@ -174,6 +174,7 @@ clear_color_image(VulkanCommandBuffer &cmd, const VkClearColorValue &value) {
 
   cmd.add_barrier(this, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                   VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT);
+  cmd.flush_barriers();
 
   VkImageSubresourceRange range;
   range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@@ -197,6 +198,7 @@ clear_depth_stencil_image(VulkanCommandBuffer &cmd, const VkClearDepthStencilVal
 
   cmd.add_barrier(this, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                   VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT);
+  cmd.flush_barriers();
 
   VkImageSubresourceRange range;
   range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;