diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-06-21 15:55:46 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-22 13:14:01 +0000 |
commit | 2e5eaf022e9389b1382cc856fcd7a8e90a078e13 (patch) | |
tree | 99948f1cd1d90d74538e17c972f102268a9e64be /src/gpu/vk | |
parent | 222958d5cbd46af9e643eb77186efceb176dd95d (diff) |
Revert "Revert "Clean up onTransferPixels""
Bug: skia:5126
Change-Id: Ia1eaef56cca266ad4c413e711e63646e913222be
Reviewed-on: https://skia-review.googlesource.com/20445
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/gpu/vk')
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 62 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 4 |
2 files changed, 62 insertions, 4 deletions
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index b10e9ed59d..d237632d9e 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -301,11 +301,13 @@ GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPatter buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern); break; case kXferCpuToGpu_GrBufferType: - SkASSERT(kStream_GrAccessPattern == accessPattern); + SkASSERT(kDynamic_GrAccessPattern == accessPattern || + kStream_GrAccessPattern == accessPattern); buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type); break; case kXferGpuToCpu_GrBufferType: - SkASSERT(kStream_GrAccessPattern == accessPattern); + SkASSERT(kDynamic_GrAccessPattern == accessPattern || + kStream_GrAccessPattern == accessPattern); buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type); break; case kTexel_GrBufferType: @@ -420,6 +422,62 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, return success; } +bool GrVkGpu::onTransferPixels(GrTexture* texture, + int left, int top, int width, int height, + GrPixelConfig config, GrBuffer* transferBuffer, + size_t bufferOffset, size_t rowBytes) { + // Vulkan only supports 4-byte aligned offsets + if (SkToBool(bufferOffset & 0x2)) { + return false; + } + GrVkTexture* vkTex = static_cast<GrVkTexture*>(texture); + if (!vkTex) { + return false; + } + GrVkTransferBuffer* vkBuffer = static_cast<GrVkTransferBuffer*>(transferBuffer); + if (!vkBuffer) { + return false; + } + + // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels. + if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) { + return false; + } + + size_t bpp = GrBytesPerPixel(config); + if (rowBytes == 0) { + rowBytes = bpp*width; + } + + // Set up copy region + VkBufferImageCopy region; + memset(®ion, 0, sizeof(VkBufferImageCopy)); + region.bufferOffset = bufferOffset; + region.bufferRowLength = (uint32_t)(rowBytes/bpp); + region.bufferImageHeight = 0; + region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.imageOffset = { left, top, 0 }; + region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 }; + + // Change layout of our target so it can be copied to + vkTex->setImageLayout(this, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + false); + + // Copy the buffer to the image + fCurrentCmdBuffer->copyBufferToImage(this, + vkBuffer, + vkTex, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + ®ion); + + vkTex->texturePriv().dirtyMipMaps(true); + return true; +} + void GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, const SkIPoint& dstPoint) { SkASSERT(dst); diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index 236b34a3c1..8a3fb09296 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -203,10 +203,10 @@ private: int left, int top, int width, int height, GrPixelConfig config, const SkTArray<GrMipLevel>&) override; - bool onTransferPixels(GrSurface*, + bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrPixelConfig config, GrBuffer* transferBuffer, - size_t offset, size_t rowBytes) override { return false; } + size_t offset, size_t rowBytes) 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 |