Fix for amd copy as draws on vulkan
authorGreg Daniel <egdaniel@google.com>
Wed, 17 May 2017 15:15:55 +0000 (11:15 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 17 May 2017 15:47:33 +0000 (15:47 +0000)
Our copies as draws have the same bug on amd as normal bugs where we need
to start a new command buffer before binding a pipeline to it.

Bug: skia:
Change-Id: If9cade2e069bf09758c5328bf606c9bd5b5aab9c
Reviewed-on: https://skia-review.googlesource.com/17213
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>

src/gpu/vk/GrVkCaps.cpp
src/gpu/vk/GrVkCaps.h
src/gpu/vk/GrVkCopyManager.cpp
src/gpu/vk/GrVkGpuCommandBuffer.cpp

index eeb43ad..9115dae 100644 (file)
@@ -20,7 +20,7 @@ GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface*
     fSupportsCopiesAsDraws = false;
     fMustSubmitCommandsBeforeCopyOp = false;
     fMustSleepOnTearDown  = false;
-    fNewSecondaryCBOnPipelineChange = false;
+    fNewCBOnPipelineChange = false;
 
     /**************************************************************************
     * GrDrawTargetCaps fields
@@ -189,7 +189,7 @@ void GrVkCaps::initGrCaps(const VkPhysicalDeviceProperties& properties,
     // AMD seems to have issues binding new VkPipelines inside a secondary command buffer.
     // Current workaround is to use a different secondary command buffer for each new VkPipeline.
     if (kAMD_VkVendor == properties.vendorID) {
-        fNewSecondaryCBOnPipelineChange = true;
+        fNewCBOnPipelineChange = true;
     }
 }
 
index e7ffe05..f599d22 100644 (file)
@@ -90,11 +90,11 @@ public:
         return fMustSleepOnTearDown;
     }
 
-    // Returns true if while adding commands to secondary command buffers, we must make a new
-    // secondary command buffer everytime we want to bind a new VkPipeline. This is to work around a
-    // driver bug specifically on AMD.
-    bool newSecondaryCBOnPipelineChange() const {
-        return fNewSecondaryCBOnPipelineChange;
+    // Returns true if while adding commands to command buffers, we must make a new command buffer
+    // everytime we want to bind a new VkPipeline. This is true for both primary and secondary
+    // command buffers. This is to work around a driver bug specifically on AMD.
+    bool newCBOnPipelineChange() const {
+        return fNewCBOnPipelineChange;
     }
 
     /**
@@ -157,7 +157,7 @@ private:
 
     bool fMustSleepOnTearDown;
 
-    bool fNewSecondaryCBOnPipelineChange;
+    bool fNewCBOnPipelineChange;
 
     typedef GrCaps INHERITED;
 };
index d0edb23..5301dea 100644 (file)
@@ -155,6 +155,11 @@ bool GrVkCopyManager::copySurfaceAsDraw(GrVkGpu* gpu,
         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();
+    }
+
     GrVkRenderTarget* rt = static_cast<GrVkRenderTarget*>(dst->asRenderTarget());
     if (!rt) {
         return false;
index 124802d..c5b8aff 100644 (file)
@@ -465,7 +465,7 @@ sk_sp<GrVkPipelineState> GrVkGpuCommandBuffer::prepareDrawState(
 
     if (!cbInfo.fIsEmpty &&
         fLastPipelineState && fLastPipelineState != pipelineState.get() &&
-        fGpu->vkCaps().newSecondaryCBOnPipelineChange()) {
+        fGpu->vkCaps().newCBOnPipelineChange()) {
         this->addAdditionalCommandBuffer();
     }
     fLastPipelineState = pipelineState.get();