Index: src/gpu/vk/GrVkGpu.cpp |
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp |
index 724a50de54d65ccdc1436667620c5b14391317d0..8e204446a2633d3ebede04dd1806dc6321f58bcd 100644 |
--- a/src/gpu/vk/GrVkGpu.cpp |
+++ b/src/gpu/vk/GrVkGpu.cpp |
@@ -365,6 +365,48 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, |
return success; |
} |
+void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target) { |
+ if (target->needsResolve()) { |
+ SkASSERT(target->numColorSamples() > 1); |
+ |
+ GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(target); |
+ SkASSERT(rt->msaaImage()); |
+ |
+ // Flip rect if necessary |
+ SkIRect srcVkRect = rt->getResolveRect(); |
+ |
+ if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { |
+ srcVkRect.fTop = rt->height() - rt->getResolveRect().fBottom; |
+ srcVkRect.fBottom = rt->height() - rt->getResolveRect().fTop; |
+ } |
+ |
+ VkImageResolve resolveInfo; |
+ resolveInfo.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
+ resolveInfo.srcOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; |
+ resolveInfo.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; |
+ resolveInfo.dstOffset = { srcVkRect.fLeft, srcVkRect.fTop, 0 }; |
+ // By the spec the depth of the extent should be ignored for 2D images, but certain devices |
+ // (e.g. nexus 5x) currently fail if it is not 1 |
+ resolveInfo.extent = { (uint32_t)srcVkRect.width(), (uint32_t)srcVkRect.height(), 1 }; |
+ |
+ rt->setImageLayout(this, |
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, |
+ VK_ACCESS_TRANSFER_WRITE_BIT, |
+ VK_PIPELINE_STAGE_TRANSFER_BIT, |
+ false); |
+ |
+ rt->msaaImage()->setImageLayout(this, |
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, |
+ VK_ACCESS_TRANSFER_READ_BIT, |
+ VK_PIPELINE_STAGE_TRANSFER_BIT, |
+ false); |
+ |
+ fCurrentCmdBuffer->resolveImage(this, *rt, *rt->msaaImage(), 1, &resolveInfo); |
+ |
+ rt->flagAsResolved(); |
+ } |
+} |
+ |
bool GrVkGpu::uploadTexDataLinear(GrVkTexture* tex, |
int left, int top, int width, int height, |
GrPixelConfig dataConfig, |