Vulkan: Don't merge render passes if read from.

In the future, we might actually track dependencies so we can smartly
sort the render passes instead.

See #11079 - screen got brighter because a cleared framebuffer was used as
a texture.
This commit is contained in:
Unknown W. Brackets 2018-05-27 14:14:02 -07:00
parent 09e85eb150
commit 423309da50
3 changed files with 21 additions and 0 deletions

View file

@ -364,6 +364,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
if (steps.size() > 1 && steps[j]->stepType == VKRStepType::RENDER &&
steps[j]->render.numDraws == 0 &&
steps[j]->render.numReads == 0 &&
steps[j]->render.color == VKRRenderPassAction::CLEAR &&
steps[j]->render.stencil == VKRRenderPassAction::CLEAR &&
steps[j]->render.depth == VKRRenderPassAction::CLEAR) {
@ -391,6 +392,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
steps[i]->copy.src == steps[j]->render.framebuffer) {
// Can't eliminate the clear if a game copies from it before it's
// rendered to. However this should be rare.
// TODO: This should never happen when we check numReads now.
break;
}
}

View file

@ -122,6 +122,8 @@ struct VKRStep {
float clearDepth;
int clearStencil;
int numDraws;
// Downloads and textures from this pass.
int numReads;
VkImageLayout finalColorLayout;
} render;
struct {

View file

@ -422,6 +422,7 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR
step->render.clearDepth = clearDepth;
step->render.clearStencil = clearStencil;
step->render.numDraws = 0;
step->render.numReads = 0;
step->render.finalColorLayout = !fb ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
steps_.push_back(step);
@ -431,6 +432,13 @@ void VulkanRenderManager::BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRR
}
bool VulkanRenderManager::CopyFramebufferToMemorySync(VKRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) {
for (int i = (int)steps_.size() - 1; i >= 0; i--) {
if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) {
steps_[i]->render.numReads++;
break;
}
}
VKRStep *step = new VKRStep{ VKRStepType::READBACK };
step->readback.aspectMask = aspectBits;
step->readback.src = src;
@ -720,6 +728,7 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect,
if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
}
steps_[i]->render.numReads++;
break;
}
}
@ -762,6 +771,13 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect,
_dbg_assert_msg_(G3D, dstRect.extent.width > 0, "blit dstwidth == 0");
_dbg_assert_msg_(G3D, dstRect.extent.height > 0, "blit dstheight == 0");
for (int i = (int)steps_.size() - 1; i >= 0; i--) {
if (steps_[i]->stepType == VKRStepType::RENDER && steps_[i]->render.framebuffer == src) {
steps_[i]->render.numReads++;
break;
}
}
VKRStep *step = new VKRStep{ VKRStepType::BLIT };
step->blit.aspectMask = aspectMask;
@ -784,6 +800,7 @@ VkImageView VulkanRenderManager::BindFramebufferAsTexture(VKRFramebuffer *fb, in
if (steps_[i]->render.finalColorLayout == VK_IMAGE_LAYOUT_UNDEFINED) {
steps_[i]->render.finalColorLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}
steps_[i]->render.numReads++;
break;
}
}