aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2016-08-04 12:50:01 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-04 12:50:01 -0700
commit52ad25151a1c7d1ac3872971f56adf15200c437e (patch)
treeb312c71aa78fec2b3e11ec779900ed741a7b09b7
parent401c1968a1727b7dd1543f7e5536ca544fc6d752 (diff)
Implement Vulkan Resolve.
First step to getting msaa running on vulkan BUG=skia:5127 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2210383002 Review-Url: https://codereview.chromium.org/2210383002
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp20
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h6
-rw-r--r--src/gpu/vk/GrVkGpu.cpp42
-rw-r--r--src/gpu/vk/GrVkGpu.h2
4 files changed, 69 insertions, 1 deletions
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index 2e474bad12..06b3bb1050 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -568,6 +568,26 @@ void GrVkPrimaryCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu,
subRanges));
}
+void GrVkPrimaryCommandBuffer::resolveImage(GrVkGpu* gpu,
+ const GrVkImage& srcImage,
+ const GrVkImage& dstImage,
+ uint32_t regionCount,
+ const VkImageResolve* regions) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+
+ this->addResource(srcImage.resource());
+ this->addResource(dstImage.resource());
+
+ GR_VK_CALL(gpu->vkInterface(), CmdResolveImage(fCmdBuffer,
+ srcImage.image(),
+ srcImage.currentLayout(),
+ dstImage.image(),
+ dstImage.currentLayout(),
+ regionCount,
+ regions));
+}
+
void GrVkPrimaryCommandBuffer::onFreeGPUData(const GrVkGpu* gpu) const {
SkASSERT(!fActiveRenderPass);
// Destroy the fence, if any
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index f439b27613..67b09c7a82 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -270,6 +270,12 @@ public:
VkDeviceSize dataSize,
const void* data);
+ void resolveImage(GrVkGpu* gpu,
+ const GrVkImage& srcImage,
+ const GrVkImage& dstImage,
+ uint32_t regionCount,
+ const VkImageResolve* regions);
+
void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync);
bool finished(const GrVkGpu* gpu) const;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 724a50de54..8e204446a2 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,
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 1554115905..841329c239 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -199,7 +199,7 @@ private:
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes) override { return false; }
- void onResolveRenderTarget(GrRenderTarget* target) override {}
+ void onResolveRenderTarget(GrRenderTarget* target) override;
// Ends and submits the current command buffer to the queue and then creates a new command
// buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all