aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-06-21 15:55:46 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-22 13:14:01 +0000
commit2e5eaf022e9389b1382cc856fcd7a8e90a078e13 (patch)
tree99948f1cd1d90d74538e17c972f102268a9e64be /src/gpu/vk
parent222958d5cbd46af9e643eb77186efceb176dd95d (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.cpp62
-rw-r--r--src/gpu/vk/GrVkGpu.h4
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(&region, 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,
+ &region);
+
+ 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