Permalink
Browse files

Fix (some) crashes on blits. Validation issues remain.

  • Loading branch information...
hrydgard committed Oct 25, 2017
1 parent 9b183f1 commit 85cb604a2477e1e52832bbacb408811dd52c2e5d
@@ -141,7 +141,7 @@ bool FramebufferManagerCommon::UpdateSize() {
void FramebufferManagerCommon::BeginFrame() {
DecimateFBOs();
currentRenderVfb_ = 0;
currentRenderVfb_ = nullptr;
updateVRAM_ = !(g_Config.iRenderingMode == FB_NON_BUFFERED_MODE || g_Config.iRenderingMode == FB_BUFFERED_MODE);
}
@@ -1043,6 +1043,11 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
void FramebufferManagerCommon::DecimateFBOs() {
currentRenderVfb_ = 0;
for (auto iter : fbosToDelete_) {
delete iter;
}
fbosToDelete_.clear();
for (size_t i = 0; i < vfbs_.size(); ++i) {
VirtualFramebuffer *vfb = vfbs_[i];
int age = frameLastFramebufUsed_ - std::max(vfb->last_frame_render, vfb->last_frame_used);
@@ -1153,7 +1158,7 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w,
BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min(vfb->bufferWidth, vfb->width), std::min(vfb->height, vfb->bufferHeight), 0);
}
}
delete old.fbo;
fbosToDelete_.push_back(old.fbo);
if (needGLESRebinds_) {
draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP });
}
@@ -190,7 +190,7 @@ class FramebufferManagerCommon {
virtual ~FramebufferManagerCommon();
virtual void Init();
void BeginFrame();
virtual void BeginFrame();
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format);
void DestroyFramebuf(VirtualFramebuffer *v);
@@ -209,6 +209,8 @@ class FramebufferManagerCommon {
FramebufferHeuristicParams inputs;
GetFramebufferHeuristicInputs(&inputs, gstate);
VirtualFramebuffer *vfb = DoSetRenderFrameBuffer(inputs, skipDrawReason);
_dbg_assert_msg_(G3D, vfb, "DoSetRenderFramebuffer must return a valid framebuffer.");
_dbg_assert_msg_(G3D, currentRenderVfb_, "DoSetRenderFramebuffer must set a valid framebuffer.");
return vfb;
}
}
@@ -412,6 +414,8 @@ class FramebufferManagerCommon {
std::map<u64, TempFBO> tempFBOs_;
std::vector<Draw::Framebuffer *> fbosToDelete_;
// Aggressively delete unused FBOs to save gpu memory.
enum {
FBO_OLD_AGE = 5,
View
@@ -1083,6 +1083,8 @@ void GPUCommon::ProcessEvent(GPUEvent ev) {
break;
case GPU_EVENT_COPY_DISPLAY_TO_OUTPUT:
// Ending the frame will unbind the framebuffer. Better finish any outstanding draw calls...
drawEngineCommon_->DispatchFlush();
CopyDisplayToOutputInternal();
break;
@@ -93,6 +93,9 @@ FramebufferManagerVulkan::FramebufferManagerVulkan(Draw::DrawContext *draw, Vulk
vulkan2D_(vulkan) {
InitDeviceObjects();
// After a blit we do need to rebind for the VulkanRenderManager to know what to do.
needGLESRebinds_ = true;
}
FramebufferManagerVulkan::~FramebufferManagerVulkan() {
@@ -580,6 +580,9 @@ void VulkanRenderManager::CopyFramebuffer(VKRFramebuffer *src, VkRect2D srcRect,
step->copy.srcRect = srcRect;
step->copy.dst = dst;
step->copy.dstPos = dstPos;
// TODO: Validate or clip copy-rectangles here.
std::unique_lock<std::mutex> lock(mutex_);
steps_.push_back(step);
curRenderStep_ = nullptr;
@@ -593,6 +596,9 @@ void VulkanRenderManager::BlitFramebuffer(VKRFramebuffer *src, VkRect2D srcRect,
step->blit.dst = dst;
step->blit.dstRect = dstRect;
step->blit.filter = filter;
// TODO: Validate blit-rectangles here.
std::unique_lock<std::mutex> lock(mutex_);
steps_.push_back(step);
curRenderStep_ = nullptr;
@@ -985,6 +991,9 @@ void VulkanRenderManager::PerformBindFramebufferAsRenderTarget(const VKRStep &st
srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
break;
}
TransitionImageLayout2(cmd, fb->color.image, VK_IMAGE_ASPECT_COLOR_BIT,
@@ -1009,6 +1018,9 @@ void VulkanRenderManager::PerformBindFramebufferAsRenderTarget(const VKRStep &st
srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
break;
default:
Crash();
break;
}
TransitionImageLayout2(cmd, fb->color.image, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
fb->color.layout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
@@ -1130,9 +1142,8 @@ void VulkanRenderManager::PerformBlit(const VKRStep &step, VkCommandBuffer cmd)
VKRFramebuffer *src = step.blit.src;
VKRFramebuffer *dst = step.blit.dst;
int srcCount = 0;
int dstCount = 0;
// If any validation needs to be performed here, it should probably have been done
// already when the blit was queued. So don't validate here.
VkImageBlit blit{};
blit.srcOffsets[0].x = step.blit.srcRect.offset.x;
blit.srcOffsets[0].y = step.blit.srcRect.offset.y;
@@ -1153,6 +1164,10 @@ void VulkanRenderManager::PerformBlit(const VKRStep &step, VkCommandBuffer cmd)
VkPipelineStageFlags srcStage = 0;
VkPipelineStageFlags dstStage = 0;
int srcCount = 0;
int dstCount = 0;
// First source barriers.
if (step.blit.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
if (src->color.layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
@@ -212,7 +212,6 @@ class VulkanRenderManager {
// Bad for performance but sometimes necessary for synchronous CPU readbacks (screenshots and whatnot).
void Sync();
void BindFramebufferAsRenderTarget(VKRFramebuffer *fb, VKRRenderPassAction color, VKRRenderPassAction depth, uint32_t clearColor, float clearDepth, uint8_t clearStencil);
VkImageView BindFramebufferAsTexture(VKRFramebuffer *fb, int binding, int aspectBit, int attachment);
@@ -364,7 +363,6 @@ class VulkanRenderManager {
int curHeight_;
bool insideFrame_ = false;
VKRStep *curRenderStep_;
VKRFramebuffer *boundFramebuffer_;
std::vector<VKRStep *> steps_;
// Execution time state

0 comments on commit 85cb604

Please sign in to comment.