Make GL & Vk backends create uninitialized backend textures

We want the non-color, non-pixel-data version of createBackendTexture to truly create uninitialized textures.

Change-Id: I08867508ea181b7ba3685638cc7a3ea11d527a24
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218396
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/gm/imagefromyuvtextures.cpp b/gm/imagefromyuvtextures.cpp
index 9db63e4..e27f04e 100644
--- a/gm/imagefromyuvtextures.cpp
+++ b/gm/imagefromyuvtextures.cpp
@@ -135,7 +135,9 @@
                                                                   kAlpha_8_SkColorType,
                                                                   GrMipMapped::kNo,
                                                                   GrRenderable::kNo,
-                                                                  fYUVBmps[i].getPixels());
+                                                                  fYUVBmps[i].getPixels(),
+                                                                  fYUVBmps[i].rowBytes(),
+                                                                  nullptr);
         }
         context->resetContext();
     }
diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp
index 7686642..8665b53 100644
--- a/gm/wacky_yuv_formats.cpp
+++ b/gm/wacky_yuv_formats.cpp
@@ -847,7 +847,7 @@
                                                                        GrSRGBEncoded::kNo);
         tex = gpu->createBackendTexture(bm.width(), bm.height(), format,
                                         GrMipMapped::kNo, GrRenderable::kNo,
-                                        pixels, 2*bm.width());
+                                        pixels, 2*bm.width(), nullptr);
     }
     if (!tex.isValid()) {
         tex = gpu->createTestingOnlyBackendTexture(
@@ -855,7 +855,7 @@
             bm.height(),
             bm.colorType(),
             GrMipMapped::kNo, GrRenderable::kNo,
-            bm.getPixels(), bm.rowBytes());
+            bm.getPixels(), bm.rowBytes(), nullptr);
     }
     return tex;
 }
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index cbb60ad..76b6317 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -354,6 +354,8 @@
 
     // If possible, create an uninitialized backend texture. The client should ensure that the
     // returned backend texture is valid.
+    // For the Vulkan backend the layout of the created VkImage will be:
+    //      VK_IMAGE_LAYOUT_UNDEFINED.
     GrBackendTexture createBackendTexture(int width, int height,
                                           GrBackendFormat,
                                           GrMipMapped,
@@ -363,6 +365,8 @@
     // returned backend texture is valid.
     // If successful, the created backend texture will be compatible with the provided
     // SkColorType.
+    // For the Vulkan backend the layout of the created VkImage will be:
+    //      VK_IMAGE_LAYOUT_UNDEFINED.
     GrBackendTexture createBackendTexture(int width, int height,
                                           SkColorType,
                                           GrMipMapped,
@@ -370,6 +374,8 @@
 
     // If possible, create a backend texture initialized to a particular color. The client should
     // ensure that the returned backend texture is valid.
+    // For the Vulkan backend the layout of the created VkImage will be:
+    //      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
     GrBackendTexture createBackendTexture(int width, int height,
                                           GrBackendFormat, const SkColor4f& color,
                                           GrMipMapped, GrRenderable);
@@ -378,6 +384,8 @@
     // ensure that the returned backend texture is valid.
     // If successful, the created backend texture will be compatible with the provided
     // SkColorType.
+    // For the Vulkan backend the layout of the created VkImage will be:
+    //      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
     GrBackendTexture createBackendTexture(int width, int height,
                                           SkColorType, const SkColor4f& color,
                                           GrMipMapped, GrRenderable);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f145754..f5cbb53 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -335,7 +335,7 @@
 
     return fGpu->createBackendTexture(width, height, backendFormat,
                                       mipMapped, renderable,
-                                      nullptr, 0);
+                                      nullptr, 0, nullptr);
 }
 
 GrBackendTexture GrContext::createBackendTexture(int width, int height,
@@ -377,7 +377,7 @@
 
     return fGpu->createBackendTexture(width, height, backendFormat,
                                       mipMapped, renderable,
-                                      nullptr, 0, color);
+                                      nullptr, 0, &color);
 }
 
 GrBackendTexture GrContext::createBackendTexture(int width, int height,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 7bbedfc..7efd5cc 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -453,14 +453,15 @@
 GrBackendTexture GrGpu::createTestingOnlyBackendTexture(int w, int h, SkColorType colorType,
                                                         GrMipMapped mipMapped,
                                                         GrRenderable renderable,
-                                                        const void* pixels, size_t rowBytes) {
+                                                        const void* pixels, size_t rowBytes,
+                                                        const SkColor4f* color) {
     GrBackendFormat format = this->caps()->getBackendFormatFromColorType(colorType);
     if (!format.isValid()) {
         return GrBackendTexture();
     }
 
     return this->createBackendTexture(w, h, format, mipMapped, renderable,
-                                      pixels, rowBytes);
+                                      pixels, rowBytes, color);
 }
 
 #if GR_TEST_UTILS
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 62d435e..ac3b687 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -381,8 +381,9 @@
     // TODO: remove this method
     GrBackendTexture createTestingOnlyBackendTexture(int w, int h, SkColorType,
                                                      GrMipMapped, GrRenderable,
-                                                     const void* pixels = nullptr,
-                                                     size_t rowBytes = 0);
+                                                     const void* pixels,
+                                                     size_t rowBytes,
+                                                     const SkColor4f* color);
 
     /**
      * Creates a texture directly in the backend API without wrapping it in a GrTexture.
@@ -394,7 +395,7 @@
     virtual GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&,
                                                   GrMipMapped, GrRenderable,
                                                   const void* pixels, size_t rowBytes,
-                                                  const SkColor4f& = SkColors::kTransparent) = 0;
+                                                  const SkColor4f* color) = 0;
 
     /**
      * Frees a texture created by createBackendTexture(). If ownership of the backend
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index d2b18f1..811b718 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4007,7 +4007,7 @@
                                                GrMipMapped mipMapped,
                                                GrRenderable renderable,
                                                const void* srcPixels, size_t rowBytes,
-                                               const SkColor4f& colorf) {
+                                               const SkColor4f* color) {
     this->handleDirtyContext();
 
     const GrGLenum* glFormat = format.getGLFormat();
@@ -4039,20 +4039,30 @@
         return GrBackendTexture();  // invalid
     }
 
-    // Figure out the number of mip levels.
-    int mipLevelCount = 1;
-    if (GrMipMapped::kYes == mipMapped) {
-        mipLevelCount = SkMipMap::ComputeLevelCount(w, h) + 1;
-    }
-
-    SkAutoTMalloc<GrMipLevel> texels(mipLevelCount);
-
+    int mipLevelCount = 0;
+    SkAutoTMalloc<GrMipLevel> texels;
     SkAutoMalloc pixelStorage;
 
-    if (!srcPixels) {
-        GrCompression compression = GrGLFormat2Compression(*glFormat);
+    if (srcPixels) {
+        mipLevelCount = 1;
 
+        texels.reset(mipLevelCount);
+
+        if (GrGLFormatIsCompressed(*glFormat)) {
+            SkASSERT(0 == rowBytes);
+        }
+
+        texels.get()[0] = { srcPixels, rowBytes };
+    } else if (color) {
+        mipLevelCount = 1;
+        if (GrMipMapped::kYes == mipMapped) {
+            mipLevelCount = SkMipMap::ComputeLevelCount(w, h) + 1;
+        }
+
+        texels.reset(mipLevelCount);
         SkTArray<size_t> individualMipOffsets(mipLevelCount);
+
+        GrCompression compression = GrGLFormat2Compression(*glFormat);
         size_t bytesPerPixel = GrBytesPerPixel(config);
 
         size_t totalSize = GrComputeTightCombinedBufferSize(compression, bytesPerPixel, w, h,
@@ -4060,7 +4070,7 @@
 
         char* tmpPixels = (char *) pixelStorage.reset(totalSize);
 
-        GrFillInData(compression, config, w, h, individualMipOffsets, tmpPixels, colorf);
+        GrFillInData(compression, config, w, h, individualMipOffsets, tmpPixels, *color);
 
         for (int i = 0; i < mipLevelCount; ++i) {
             size_t offset = individualMipOffsets[i];
@@ -4070,14 +4080,6 @@
 
             texels.get()[i] = { &(tmpPixels[offset]), currentWidth*bytesPerPixel };
         }
-    } else {
-        SkASSERT(1 == mipLevelCount);
-
-        if (GrGLFormatIsCompressed(*glFormat)) {
-            SkASSERT(0 == rowBytes);
-        }
-
-        texels.get()[0] = { srcPixels, rowBytes };
     }
 
     GrSurfaceDesc desc;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index ac9bf9a..23b5fb6 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -139,7 +139,7 @@
     GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&,
                                           GrMipMapped, GrRenderable,
                                           const void* pixels, size_t rowBytes,
-                                          const SkColor4f& color = SkColors::kTransparent) override;
+                                          const SkColor4f* color) override;
     void deleteBackendTexture(const GrBackendTexture&) override;
 
 #if GR_TEST_UTILS
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 3c67b63..17ec170 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -202,7 +202,7 @@
                                                  GrRenderable /* renderable */,
                                                  const void* /* pixels */,
                                                  size_t /* rowBytes */,
-                                                 const SkColor4f& /* color */) {
+                                                 const SkColor4f* /* color */) {
 
     const GrPixelConfig* pixelConfig = format.getMockFormat();
     if (!pixelConfig) {
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index de3af71..e63e51d 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -123,7 +123,7 @@
     GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&,
                                           GrMipMapped, GrRenderable,
                                           const void* pixels, size_t rowBytes,
-                                          const SkColor4f& color = SkColors::kTransparent) override;
+                                          const SkColor4f* color) override;
     void deleteBackendTexture(const GrBackendTexture&) override;
 
 #if GR_TEST_UTILS
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 32c22fc..48c0247 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -58,7 +58,7 @@
     GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&,
                                           GrMipMapped, GrRenderable,
                                           const void* pixels, size_t rowBytes,
-                                          const SkColor4f& color = SkColors::kTransparent) override;
+                                          const SkColor4f* color) override;
 
     void deleteBackendTexture(const GrBackendTexture&) override;
 
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 1387c31..bcd1514 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -771,7 +771,7 @@
                                                 GrMipMapped mipMapped,
                                                 GrRenderable renderable,
                                                 const void* pixels, size_t rowBytes,
-                                                const SkColor4f& color) {
+                                                const SkColor4f* color) {
     if (w > this->caps()->maxTextureSize() || h > this->caps()->maxTextureSize()) {
         return GrBackendTexture();
     }
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 873ac8b..ee0f171 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1364,7 +1364,6 @@
 
     // setup memory barrier
     SkASSERT(GrVkFormatIsSupported(vkTex->imageFormat()));
-    VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
     VkImageMemoryBarrier imageMemoryBarrier = {
             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,  // sType
             nullptr,                                 // pNext
@@ -1375,7 +1374,7 @@
             VK_QUEUE_FAMILY_IGNORED,                 // srcQueueFamilyIndex
             VK_QUEUE_FAMILY_IGNORED,                 // dstQueueFamilyIndex
             vkTex->image(),                          // image
-            {aspectFlags, 0, 1, 0, 1}                // subresourceRange
+            {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}  // subresourceRange
     };
 
     // Blit the miplevels
@@ -1498,9 +1497,39 @@
     return true;
 }
 
+static void set_image_layout(const GrVkInterface* vkInterface, VkCommandBuffer cmdBuffer,
+                             GrVkImageInfo* info, VkImageLayout newLayout, uint32_t mipLevels,
+                             VkAccessFlagBits dstAccessMask, VkPipelineStageFlagBits dstStageMask) {
+    VkAccessFlags srcAccessMask = GrVkImage::LayoutToSrcAccessMask(info->fImageLayout);
+    VkPipelineStageFlags srcStageMask = GrVkImage::LayoutToPipelineSrcStageFlags(
+                                                                              info->fImageLayout);
+
+    VkImageMemoryBarrier barrier;
+    memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
+    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    barrier.pNext = nullptr;
+    barrier.srcAccessMask = srcAccessMask;
+    barrier.dstAccessMask = dstAccessMask;
+    barrier.oldLayout = info->fImageLayout;
+    barrier.newLayout = newLayout;
+    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+    barrier.image = info->fImage;
+    barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0, 1};
+    GR_VK_CALL(vkInterface, CmdPipelineBarrier(
+                               cmdBuffer,
+                               srcStageMask,
+                               dstStageMask,
+                               0,
+                               0, nullptr,
+                               0, nullptr,
+                               1, &barrier));
+    info->fImageLayout = newLayout;
+}
+
 bool GrVkGpu::createTestingOnlyVkImage(GrPixelConfig config, int w, int h, bool texturable,
                                        bool renderable, GrMipMapped mipMapped, const void* srcData,
-                                       size_t srcRowBytes, const SkColor4f& color,
+                                       size_t srcRowBytes, const SkColor4f* color,
                                        GrVkImageInfo* info) {
     SkASSERT(texturable || renderable);
     if (!texturable) {
@@ -1556,7 +1585,12 @@
         return false;
     }
 
-    // We need to declare these early so that we can delete them at the end outside of the if block.
+    if (!srcData && !color) {
+        return true;
+    }
+
+    // We need to declare these early so that we can delete them at the end outside of
+    // the if block.
     GrVkAlloc bufferAlloc;
     VkBuffer buffer = VK_NULL_HANDLE;
 
@@ -1626,7 +1660,7 @@
     bool result;
     if (!srcData) {
         result = fill_in_with_color(this, bufferAlloc, vkFormat, w, h, individualMipOffsets,
-                                    config, color);
+                                    config, *color);
     } else {
         SkASSERT(1 == mipLevels);
 
@@ -1642,26 +1676,10 @@
         return false;
     }
 
-
     // Set image layout and add barrier
-    VkImageMemoryBarrier barrier;
-    memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
-    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
-    barrier.pNext = nullptr;
-    barrier.srcAccessMask = GrVkImage::LayoutToSrcAccessMask(info->fImageLayout);
-    barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
-    barrier.oldLayout = info->fImageLayout;
-    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
-    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-    barrier.image = info->fImage;
-    barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0, 1};
-
-    VK_CALL(CmdPipelineBarrier(cmdBuffer,
-                               GrVkImage::LayoutToPipelineSrcStageFlags(info->fImageLayout),
-                               VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1,
-                               &barrier));
-    info->fImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+    set_image_layout(this->vkInterface(), cmdBuffer, info,
+                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, mipLevels,
+                     VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 
     SkTArray<VkBufferImageCopy> regions(mipLevels);
 
@@ -1685,27 +1703,11 @@
                                  regions.count(), regions.begin()));
 
     if (texturable) {
-        // Change Image layout to shader read since if we use this texture as a borrowed textures
-        // within Ganesh we require that its layout be set to that
-        memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
-        barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
-        barrier.pNext = nullptr;
-        barrier.srcAccessMask = GrVkImage::LayoutToSrcAccessMask(info->fImageLayout);
-        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-        barrier.oldLayout = info->fImageLayout;
-        barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-        barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
-        barrier.image = info->fImage;
-        barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0, 1};
-        VK_CALL(CmdPipelineBarrier(cmdBuffer,
-                                   GrVkImage::LayoutToPipelineSrcStageFlags(info->fImageLayout),
-                                   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
-                                   0,
-                                   0, nullptr,
-                                   0, nullptr,
-                                   1, &barrier));
-        info->fImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+        // Change Image layout to shader read since if we use this texture as a borrowed
+        // texture within Ganesh we require that its layout be set to that
+        set_image_layout(this->vkInterface(), cmdBuffer, info,
+                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, mipLevels,
+                         VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
     }
 
     // End CommandBuffer
@@ -1713,10 +1715,12 @@
     SkASSERT(!err);
 
     // Create Fence for queue
-    VkFence fence;
     VkFenceCreateInfo fenceInfo;
     memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fenceInfo.pNext = nullptr;
+    fenceInfo.flags = 0;
+    VkFence fence = VK_NULL_HANDLE;
 
     err = VK_CALL(CreateFence(fDevice, &fenceInfo, nullptr, &fence));
     SkASSERT(!err);
@@ -1735,13 +1739,15 @@
     err = VK_CALL(QueueSubmit(this->queue(), 1, &submitInfo, fence));
     SkASSERT(!err);
 
-    err = VK_CALL(WaitForFences(fDevice, 1, &fence, true, UINT64_MAX));
+    err = VK_CALL(WaitForFences(this->device(), 1, &fence, VK_TRUE, UINT64_MAX));
     if (VK_TIMEOUT == err) {
         GrVkImage::DestroyImageInfo(this, info);
-        GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
-        VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+        if (buffer != VK_NULL_HANDLE) { // workaround for an older NVidia driver crash
+            GrVkMemory::FreeBufferMemory(this, GrVkBuffer::kCopyRead_Type, bufferAlloc);
+            VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
+        }
         VK_CALL(FreeCommandBuffers(fDevice, fCmdPool->vkCommandPool(), 1, &cmdBuffer));
-        VK_CALL(DestroyFence(fDevice, fence, nullptr));
+        VK_CALL(DestroyFence(this->device(), fence, nullptr));
         SkDebugf("Fence failed to signal: %d\n", err);
         SK_ABORT("failing");
     }
@@ -1753,7 +1759,7 @@
         VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
     }
     VK_CALL(FreeCommandBuffers(fDevice, fCmdPool->vkCommandPool(), 1, &cmdBuffer));
-    VK_CALL(DestroyFence(fDevice, fence, nullptr));
+    VK_CALL(DestroyFence(this->device(), fence, nullptr));
 
     return true;
 }
@@ -1835,7 +1841,7 @@
                                                GrMipMapped mipMapped,
                                                GrRenderable renderable,
                                                const void* srcData, size_t rowBytes,
-                                               const SkColor4f& color) {
+                                               const SkColor4f* color) {
     this->handleDirtyContext();
 
     if (w > this->caps()->maxTextureSize() || h > this->caps()->maxTextureSize()) {
@@ -1916,7 +1922,7 @@
 
     GrVkImageInfo info;
     if (!this->createTestingOnlyVkImage(config, w, h, false, true, GrMipMapped::kNo, nullptr, 0,
-                                        SkColors::kTransparent, &info)) {
+                                        &SkColors::kTransparent, &info)) {
         return {};
     }
     GrBackendRenderTarget beRT = GrBackendRenderTarget(w, h, 1, 0, info);
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index d1b2d98..70a1ce5 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -82,7 +82,7 @@
     GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&,
                                           GrMipMapped, GrRenderable,
                                           const void* pixels, size_t rowBytes,
-                                          const SkColor4f& color = SkColors::kTransparent) override;
+                                          const SkColor4f* color) override;
     void deleteBackendTexture(const GrBackendTexture&) override;
 #if GR_TEST_UTILS
     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
@@ -261,7 +261,7 @@
 
     bool createTestingOnlyVkImage(GrPixelConfig config, int w, int h, bool texturable,
                                   bool renderable, GrMipMapped mipMapped, const void* srcData,
-                                  size_t srcRowBytes, const SkColor4f& color, GrVkImageInfo* info);
+                                  size_t srcRowBytes, const SkColor4f* color, GrVkImageInfo* info);
 
     sk_sp<const GrVkInterface>                            fInterface;
     sk_sp<GrVkMemoryAllocator>                            fMemoryAllocator;
diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp
index 9eaa26c..f66c70c 100644
--- a/src/gpu/vk/GrVkImage.cpp
+++ b/src/gpu/vk/GrVkImage.cpp
@@ -137,8 +137,8 @@
     VkImageMemoryBarrier imageMemoryBarrier = {
         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,          // sType
         nullptr,                                         // pNext
-        srcAccessMask,                                   // outputMask
-        dstAccessMask,                                   // inputMask
+        srcAccessMask,                                   // srcAccessMask
+        dstAccessMask,                                   // dstAccessMask
         currentLayout,                                   // oldLayout
         newLayout,                                       // newLayout
         srcQueueFamilyIndex,                             // srcQueueFamilyIndex
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 97230e1..798ff6e 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -634,8 +634,17 @@
                     auto uninitCreateMtd = [format](GrContext* context,
                                                     GrMipMapped mipMapped,
                                                     GrRenderable renderable) {
-                        return context->createBackendTexture(32, 32, format,
-                                                             mipMapped, renderable);
+                        GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
+                                                                               mipMapped,
+                                                                               renderable);
+                        GrVkImageInfo vkII;
+                        if (!beTex.getVkImageInfo(&vkII)) {
+                            return GrBackendTexture();
+                        }
+
+                        SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == vkII.fImageLayout);
+                        SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
+                        return beTex;
                     };
 
                     test_wrapping(context, reporter, uninitCreateMtd,
@@ -647,8 +656,17 @@
                                                        const SkColor4f& color,
                                                        GrMipMapped mipMapped,
                                                        GrRenderable renderable) {
-                        return context->createBackendTexture(32, 32, format, color,
-                                                             mipMapped, renderable);
+                        GrBackendTexture beTex = context->createBackendTexture(32, 32, format,
+                                                                               color, mipMapped,
+                                                                               renderable);
+                        GrVkImageInfo vkII;
+                        if (!beTex.getVkImageInfo(&vkII)) {
+                            return GrBackendTexture();
+                        }
+
+                        SkASSERT(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == vkII.fImageLayout);
+                        SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
+                        return beTex;
                     };
 
                     test_color_init(context, reporter, createWithColorMtd,
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index a6db616..3c2e9cc 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -290,7 +290,7 @@
     for (auto ioType : {kRead_GrIOType, kRW_GrIOType}) {
         auto backendTex = context->priv().getGpu()->createTestingOnlyBackendTexture(
                 kSize, kSize, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kYes,
-                pixels.addr());
+                pixels.addr(), 0, nullptr);
         auto proxy = proxyProvider->wrapBackendTexture(backendTex, kTopLeft_GrSurfaceOrigin,
                                                        kBorrow_GrWrapOwnership,
                                                        GrWrapCacheable::kNo, ioType);
diff --git a/tests/GrTestingBackendTextureUploadTest.cpp b/tests/GrTestingBackendTextureUploadTest.cpp
index 8642c6a..491b334 100644
--- a/tests/GrTestingBackendTextureUploadTest.cpp
+++ b/tests/GrTestingBackendTextureUploadTest.cpp
@@ -46,7 +46,8 @@
 
     GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
                                         kWidth, kHeight, ct,
-                                        mipMapped, renderable, srcBuffer);
+                                        mipMapped, renderable, srcBuffer, 0,
+                                        &SkColors::kTransparent);
     if (!backendTex.isValid()) {
         return;
     }
diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp
index a63e656..74a2c72 100644
--- a/tests/TestUtils.cpp
+++ b/tests/TestUtils.cpp
@@ -112,7 +112,7 @@
 
     *backendTex = gpu->createTestingOnlyBackendTexture(ii.width(), ii.height(), ii.colorType(),
                                                        mipMapped, renderable,
-                                                       bm.getPixels(), bm.rowBytes());
+                                                       bm.getPixels(), bm.rowBytes(), nullptr);
     if (!backendTex->isValid() || !gpu->isTestingOnlyBackendTexture(*backendTex)) {
         return false;
     }
diff --git a/tools/DDLPromiseImageHelper.cpp b/tools/DDLPromiseImageHelper.cpp
index 7479113..790699c 100644
--- a/tools/DDLPromiseImageHelper.cpp
+++ b/tools/DDLPromiseImageHelper.cpp
@@ -86,12 +86,12 @@
                                                                        GrSRGBEncoded::kNo);
         tex = gpu->createBackendTexture(pm.width(), pm.height(), format,
                                         GrMipMapped::kNo, GrRenderable::kNo,
-                                        pixels, 2 * pm.width());
+                                        pixels, 2 * pm.width(), nullptr);
     } else {
         tex = gpu->createTestingOnlyBackendTexture(
             pm.width(), pm.height(), pm.colorType(),
             GrMipMapped::kNo, GrRenderable::kNo,
-            pm.addr(), pm.rowBytes());
+            pm.addr(), pm.rowBytes(), nullptr);
     }
     return tex;
 }
@@ -128,7 +128,7 @@
             callbackContext->setBackendTexture(gpu->createTestingOnlyBackendTexture(
                                                         bm.width(), bm.height(), bm.colorType(),
                                                         GrMipMapped::kNo, GrRenderable::kNo,
-                                                        bm.getPixels(), bm.rowBytes()));
+                                                        bm.getPixels(), bm.rowBytes(), nullptr));
             // The GMs sometimes request too large an image
             //SkAssertResult(callbackContext->backendTexture().isValid());