aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGreg Daniel <egdaniel@google.com>2018-03-19 13:18:15 -0400
committerGreg Daniel <egdaniel@google.com>2018-03-19 18:15:06 +0000
commitfc8aecf35134558c27976177961b4b027022cb8a (patch)
tree4b5d0b5f64d2b0812144724194b8eea5eb51234e /src
parent9017bd84481704bebf5737f3a7eb2e51f529401d (diff)
downloadskqp-fc8aecf35134558c27976177961b4b027022cb8a.tar.gz
Correctly discard or load RT when doing copies as draws in Vulkan
This fixes all the copy as draw issues we've had with certain devices and the cap is no longer needed. Bug: skia: Change-Id: Id0b750849c4c920beae2d8cb3eda5f402018f194 Reviewed-On: https://skia-review.googlesource.com/114860 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-By: Brian Salomon <bsalomon@google.com> Reviewed-on: https://skia-review.googlesource.com/115081
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrContext.cpp7
-rw-r--r--src/gpu/GrGpu.cpp6
-rw-r--r--src/gpu/GrGpu.h9
-rw-r--r--src/gpu/ddl/GrDDLGpu.h3
-rw-r--r--src/gpu/gl/GrGLGpu.cpp3
-rw-r--r--src/gpu/gl/GrGLGpu.h3
-rw-r--r--src/gpu/mock/GrMockGpu.h10
-rw-r--r--src/gpu/mtl/GrMtlGpu.h3
-rw-r--r--src/gpu/vk/GrVkCaps.cpp10
-rw-r--r--src/gpu/vk/GrVkCaps.h7
-rw-r--r--src/gpu/vk/GrVkCopyManager.cpp15
-rw-r--r--src/gpu/vk/GrVkCopyManager.h3
-rw-r--r--src/gpu/vk/GrVkGpu.cpp9
-rw-r--r--src/gpu/vk/GrVkGpu.h8
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp7
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.h9
16 files changed, 61 insertions, 51 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 0e8b60f63c..368d83f231 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -842,7 +842,12 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfac
return nullptr;
}
- return this->makeWrappedSurfaceContext(std::move(proxy));
+ sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy));
+ if (sContext && sContext->asRenderTargetContext()) {
+ sContext->asRenderTargetContext()->discard();
+ }
+
+ return sContext;
}
sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackendTexture& tex,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index bea6a601e6..f2bbda170b 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -241,7 +241,8 @@ GrBuffer* GrGpu::createBuffer(size_t size, GrBufferType intendedType,
bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) {
GR_CREATE_TRACE_MARKER_CONTEXT("GrGpu", "copySurface", fContext);
SkASSERT(dst && src);
this->handleDirtyContext();
@@ -249,7 +250,8 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
if (GrPixelConfigIsSint(dst->config()) != GrPixelConfigIsSint(src->config())) {
return false;
}
- return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
+ return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint,
+ canDiscardOutsideDstRect);
}
bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 2f12073f8a..30e565fe90 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -322,11 +322,13 @@ public:
// Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
// take place at the GrOpList level and this function implement faster copy paths. The rect
// and point are pre-clipped. The src rect and implied dst rect are guaranteed to be within the
- // src/dst bounds and non-empty.
+ // src/dst bounds and non-empty. If canDiscardOutsideDstRect is set to true then we don't need
+ // to preserve any data on the dst surface outside of the copy.
bool copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,
- const SkIPoint& dstPoint);
+ const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect = false);
struct MultisampleSpecs {
MultisampleSpecs(uint8_t uniqueID, int effectiveSampleCnt, const SkPoint* locations)
@@ -597,7 +599,8 @@ private:
// overridden by backend specific derived class to perform the copy surface
virtual bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) = 0;
// overridden by backend specific derived class to perform the multisample queries
virtual void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin rtOrigin,
diff --git a/src/gpu/ddl/GrDDLGpu.h b/src/gpu/ddl/GrDDLGpu.h
index e1f463f073..0508a2e3b0 100644
--- a/src/gpu/ddl/GrDDLGpu.h
+++ b/src/gpu/ddl/GrDDLGpu.h
@@ -38,7 +38,8 @@ public:
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) override {
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) override {
SkASSERT(0);
return true;
}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e117488647..fb0622beb5 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3476,7 +3476,8 @@ void GrGLGpu::unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface
bool GrGLGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) {
// None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
// swizzle.
if (this->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 9ac86ba123..0d55e50d09 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -265,7 +265,8 @@ private:
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) override;
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) override;
void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) override;
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 5185ce28f0..b99857f8b6 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -35,10 +35,6 @@ public:
GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) override { return true; }
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) override { return true; }
-
void onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) override {
*effectiveSampleCnt = rt->numStencilSamples();
@@ -123,6 +119,12 @@ private:
void onResolveRenderTarget(GrRenderTarget* target, GrSurfaceOrigin) override { return; }
+ bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
+ GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override {
+ return true;
+ }
+
void onFinishFlush(bool insertedSemaphores) override {}
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 5a5289b6e1..9199f0389c 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -44,7 +44,8 @@ public:
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,
- const SkIPoint& dstPoint) override { return false; }
+ const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) override { return false; }
void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) override {}
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index e56d0e8205..f25c8d7b64 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -19,7 +19,6 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
: INHERITED(contextOptions) {
fCanUseGLSLForShaderModule = false;
fMustDoCopiesFromOrigin = false;
- fSupportsCopiesAsDraws = true;
fMustSubmitCommandsBeforeCopyOp = false;
fMustSleepOnTearDown = false;
fNewCBOnPipelineChange = false;
@@ -64,7 +63,7 @@ bool GrVkCaps::initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc*
// render target as well.
desc->fOrigin = src->origin();
desc->fConfig = src->config();
- if (src->numColorSamples() > 1 || (src->asTextureProxy() && this->supportsCopiesAsDraws())) {
+ if (src->numColorSamples() > 1 || src->asTextureProxy()) {
desc->fFlags = kRenderTarget_GrSurfaceFlag;
} else {
// Just going to use CopyImage here
@@ -115,13 +114,6 @@ void GrVkCaps::applyDriverCorrectnessWorkarounds(const VkPhysicalDevicePropertie
fMustSubmitCommandsBeforeCopyOp = true;
}
- if (kQualcomm_VkVendor == properties.vendorID ||
- kARM_VkVendor == properties.vendorID) {
- fSupportsCopiesAsDraws = false;
- // We require copies as draws to support cross context textures.
- fCrossContextTextureSupport = false;
- }
-
#if defined(SK_BUILD_FOR_WIN)
if (kNvidia_VkVendor == properties.vendorID) {
fMustSleepOnTearDown = true;
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 90f488ee9f..75ef935f8d 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -73,11 +73,6 @@ public:
return fMustDoCopiesFromOrigin;
}
- // Check whether we support using draws for copies.
- bool supportsCopiesAsDraws() const {
- return fSupportsCopiesAsDraws;
- }
-
// On Nvidia there is a current bug where we must the current command buffer before copy
// operations or else the copy will not happen. This includes copies, blits, resolves, and copy
// as draws.
@@ -172,8 +167,6 @@ private:
bool fMustDoCopiesFromOrigin;
- bool fSupportsCopiesAsDraws;
-
bool fMustSubmitCommandsBeforeCopyOp;
bool fMustSleepOnTearDown;
diff --git a/src/gpu/vk/GrVkCopyManager.cpp b/src/gpu/vk/GrVkCopyManager.cpp
index ba62980b74..e3e0e092fe 100644
--- a/src/gpu/vk/GrVkCopyManager.cpp
+++ b/src/gpu/vk/GrVkCopyManager.cpp
@@ -143,7 +143,8 @@ bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) {
bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) {
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) {
// None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
// swizzle.
if (gpu->caps()->shaderCaps()->configOutputSwizzle(src->config()) !=
@@ -151,10 +152,6 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
return false;
}
- if (!gpu->vkCaps().supportsCopiesAsDraws()) {
- return false;
- }
-
if (gpu->vkCaps().newCBOnPipelineChange()) {
// We bind a new pipeline here for the copy so we must start a new command buffer.
gpu->finishFlush(0, nullptr);
@@ -324,13 +321,13 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
false);
}
- GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_DONT_CARE,
- VK_ATTACHMENT_STORE_OP_STORE);
+ VkAttachmentLoadOp loadOp = canDiscardOutsideDstRect ? VK_ATTACHMENT_LOAD_OP_DONT_CARE
+ : VK_ATTACHMENT_LOAD_OP_LOAD;
+ GrVkRenderPass::LoadStoreOps vkColorOps(loadOp, VK_ATTACHMENT_STORE_OP_STORE);
GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE);
const GrVkRenderPass* renderPass;
- const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
- rt->compatibleRenderPassHandle();
+ const GrVkResourceProvider::CompatibleRPHandle& rpHandle = rt->compatibleRenderPassHandle();
if (rpHandle.isValid()) {
renderPass = gpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
diff --git a/src/gpu/vk/GrVkCopyManager.h b/src/gpu/vk/GrVkCopyManager.h
index 726faf30d3..f36cc302b4 100644
--- a/src/gpu/vk/GrVkCopyManager.h
+++ b/src/gpu/vk/GrVkCopyManager.h
@@ -30,7 +30,8 @@ public:
bool copySurfaceAsDraw(GrVkGpu* gpu,
GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint);
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect);
void destroyResources(GrVkGpu* gpu);
void abandonResources();
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 9428e134af..1269eaa423 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1861,8 +1861,8 @@ void GrVkGpu::copySurfaceAsResolve(GrSurface* dst, GrSurfaceOrigin dstOrigin,
bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect,
- const SkIPoint& dstPoint) {
+ const SkIRect& srcRect, const SkIPoint& dstPoint,
+ bool canDiscardOutsideDstRect) {
if (can_copy_as_resolve(dst, dstOrigin, src, srcOrigin, this)) {
this->copySurfaceAsResolve(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
return true;
@@ -1872,7 +1872,10 @@ bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
this->submitCommandBuffer(GrVkGpu::kSkip_SyncQueue);
}
- if (fCopyManager.copySurfaceAsDraw(this, dst, dstOrigin, src, srcOrigin, srcRect, dstPoint)) {
+ if (fCopyManager.copySurfaceAsDraw(this, dst, dstOrigin, src, srcOrigin, srcRect, dstPoint,
+ canDiscardOutsideDstRect)) {
+ auto dstRect = srcRect.makeOffset(dstPoint.fX, dstPoint.fY);
+ this->didWriteToSurface(dst, &dstRect);
return true;
}
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 114d97c0b2..85fb213238 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -77,10 +77,6 @@ public:
GrPixelConfig srcConfig, DrawPreference*,
WritePixelTempDrawInfo*) override;
- bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
- GrSurface* src, GrSurfaceOrigin srcOrigin,
- const SkIRect& srcRect, const SkIPoint& dstPoint) override;
-
void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
int* effectiveSampleCnt, SamplePattern*) override;
@@ -211,6 +207,10 @@ private:
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes) override;
+ bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
+ GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
+ const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override;
+
void onFinishFlush(bool insertedSemaphores) override;
// Ends and submits the current command buffer to the queue and then creates a new command
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index dcc5e65ca4..7bf07bce98 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -174,7 +174,7 @@ void GrVkGpuRTCommandBuffer::submit() {
for (int j = 0; j < cbInfo.fPreCopies.count(); ++j) {
CopyInfo& copyInfo = cbInfo.fPreCopies[j];
fGpu->copySurface(fRenderTarget, fOrigin, copyInfo.fSrc, copyInfo.fSrcOrigin,
- copyInfo.fSrcRect, copyInfo.fDstPoint);
+ copyInfo.fSrcRect, copyInfo.fDstPoint, copyInfo.fShouldDiscardDst);
}
// Make sure we do the following layout changes after all copies, uploads, or any other pre
@@ -476,6 +476,10 @@ void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, con
this->addAdditionalRenderPass();
}
+ fCommandBufferInfos[fCurrentCmdInfo].fPreCopies.emplace_back(
+ src, srcOrigin, srcRect, dstPoint,
+ LoadStoreState::kStartsWithDiscard == cbInfo.fLoadStoreState);
+
if (LoadStoreState::kLoadAndStore != cbInfo.fLoadStoreState) {
// Change the render pass to do a load and store so we don't lose the results of our copy
GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
@@ -503,7 +507,6 @@ void GrVkGpuRTCommandBuffer::copy(GrSurface* src, GrSurfaceOrigin srcOrigin, con
cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
}
- fCommandBufferInfos[fCurrentCmdInfo].fPreCopies.emplace_back(src, srcOrigin, srcRect, dstPoint);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h
index 2e9ac12bd4..f2d48c7ab0 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.h
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.h
@@ -143,13 +143,18 @@ private:
struct CopyInfo {
CopyInfo(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
- const SkIPoint& dstPoint)
- : fSrc(src), fSrcOrigin(srcOrigin), fSrcRect(srcRect), fDstPoint(dstPoint) {}
+ const SkIPoint& dstPoint, bool shouldDiscardDst)
+ : fSrc(src)
+ , fSrcOrigin(srcOrigin)
+ , fSrcRect(srcRect)
+ , fDstPoint(dstPoint)
+ , fShouldDiscardDst(shouldDiscardDst) {}
GrSurface* fSrc;
GrSurfaceOrigin fSrcOrigin;
SkIRect fSrcRect;
SkIPoint fDstPoint;
+ bool fShouldDiscardDst;
};
enum class LoadStoreState {