Просмотр исходного кода

Vulkan: Use more optimal layout for depth-stencil buffer bound both as shader input and a FB attachment

BearishSun 9 лет назад
Родитель
Сommit
e47adb4658

+ 5 - 20
Source/BansheeVulkanRenderAPI/Source/BsVulkanCommandBuffer.cpp

@@ -1407,26 +1407,11 @@ namespace bs
 
 			imageInfo.accessFlags |= accessFlags;
 
-			// We allow undefied layout to be passed as a convience. Essentially it means that no layout transition should
-			// happen.
-			if(newLayout != VK_IMAGE_LAYOUT_UNDEFINED)
-			{
-				bool firstUseInRenderPass = !imageInfo.isShaderInput && !imageInfo.isFBAttachment;
-
-				// If image was previously used this render pass, check if it is used with different layouts, in which case
-				// we need to transfer to the general layout
-				if (!firstUseInRenderPass && imageInfo.requiredLayout != newLayout)
-				{
-					// If required layout is set to undefined it only means didn't want to issue a layout transition,
-					// therefore no need to switch to GENERAL layout, instead just override the undefined layout.
-					if (imageInfo.requiredLayout != VK_IMAGE_LAYOUT_UNDEFINED)
-						imageInfo.requiredLayout = VK_IMAGE_LAYOUT_GENERAL;
-					else
-						imageInfo.requiredLayout = newLayout;
-				}
-				else
-					imageInfo.requiredLayout = newLayout;
-			}
+			// Note: We purposely ignore the "newLayout" param here. Almost all textures can only be in one layout (after
+			// the initial transition), so we keep the layout that they were originally registered with. The only exception
+			// are framebuffer attachments (that can be bound as attachments, or as normal textures, or both). However, we 
+			// handle FB attachment layouts through automatic layout transitions controlled by render-pass so no need
+			// to set them here.
 
 			// If attached to FB, then the final layout is set by the FB (provided as layout param here), otherwise its
 			// the same as required layout

+ 3 - 1
Source/BansheeVulkanRenderAPI/Source/BsVulkanFramebuffer.cpp

@@ -235,8 +235,10 @@ namespace bs
 				attachmentDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 			}
 
+			// When depth-stencil is readable it's up to the caller to ensure he doesn't try to write to it as well, so we
+			// just assume a read-only layout.
 			if (readMask.isSet(RT_DEPTH))
-				attachmentRef.layout = VK_IMAGE_LAYOUT_GENERAL;
+				attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
 			else
 				attachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
 		}

+ 3 - 0
Source/BansheeVulkanRenderAPI/Source/BsVulkanTexture.cpp

@@ -307,6 +307,9 @@ namespace bs
 		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
 			accessFlags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
 			break;
+		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
+			accessFlags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT;
+			break;
 		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
 			accessFlags = VK_ACCESS_SHADER_READ_BIT;
 			break;