Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Unified Diff: src/gpu/vk/GrVkGpu.cpp

Issue 1888473002: Use transfer buffer for BatchAtlas texture copies Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix Chrome Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/gpu/GrBatchAtlas.cpp ('K') | « src/gpu/vk/GrVkGpu.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/vk/GrVkGpu.cpp
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 28dce344be37659f0e18b4fbd768dc0b7164461f..88b9542a032c51753083d7c2b935e0959b30df5e 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -183,10 +183,12 @@ GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPatter
kStatic_GrAccessPattern == accessPattern);
return GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
case kXferCpuToGpu_GrBufferType:
- SkASSERT(kStream_GrAccessPattern == accessPattern);
+ SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
+ kStream_GrAccessPattern == accessPattern);
return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type);
case kXferGpuToCpu_GrBufferType:
- SkASSERT(kStream_GrAccessPattern == accessPattern);
+ SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
+ kStream_GrAccessPattern == accessPattern);
return GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type);
default:
SkFAIL("Unknown buffer type.");
@@ -274,6 +276,100 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
return false;
}
+
+bool GrVkGpu::onTransferPixels(GrSurface* surface,
+ int left, int top, int width, int height,
+ GrPixelConfig config, GrBuffer* transferBuffer,
+ size_t bufferOffset, size_t rowBytes) {
+ GrVkTexture* vkTex = static_cast<GrVkTexture*>(surface->asTexture());
+ if (!vkTex) {
egdaniel 2016/04/18 16:46:34 why do you require that this is a texture for vulk
jvanverth1 2016/04/19 17:14:27 The expected use case for this is to transfer CPU-
egdaniel 2016/04/19 17:22:18 Well if we don't want to OpenGL and Vulkan be diff
bsalomon 2016/04/19 18:19:26 If we are only planning to use it with textures an
+ 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(surface->config()) != GrPixelConfigIsSRGB(config)) {
+ return false;
+ }
+
+ // TODO: Not clear how to handle y axis flip
egdaniel 2016/04/18 16:46:34 well I guess there are two options here. First wou
jvanverth1 2016/04/19 17:14:27 The temp image seems like the best bet -- I'm goin
+ if (kBottomLeft_GrSurfaceOrigin == vkTex->origin()) {
+ return false;
+ }
+
+ bool success = false;
+ if (GrPixelConfigIsCompressed(vkTex->desc().fConfig)) {
+ // We check that config == desc.fConfig in GrGpu::getWritePixelsInfo()
+ SkASSERT(config == vkTex->desc().fConfig);
+ // TODO: add compressed texture support
+ // delete the following two lines and uncomment the two after that when ready
+ vkTex->unref();
+ return false;
+ //success = this->uploadCompressedTexData(vkTex->desc(), buffer, false, left, top, width,
+ // height);
+ } else {
+ // make sure the unmap has finished
+ vkBuffer->addMemoryBarrier(this,
+ VK_ACCESS_HOST_WRITE_BIT,
+ VK_ACCESS_TRANSFER_READ_BIT,
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ false);
+
+ // Set up copy region
+ VkOffset3D offset = {
egdaniel 2016/04/18 16:46:34 why not just inline this like subresource or exten
jvanverth1 2016/04/19 17:14:27 Done.
+ left,
+ top,
+ 0
+ };
+ size_t bpp = GrBytesPerPixel(config);
+
+ 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 = offset;
+ region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
+
+ // Change layout of our target so it can be copied to
+ VkImageLayout layout = vkTex->currentLayout();
+ VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout);
+ VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT;
+ VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout);
+ VkAccessFlags dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ vkTex->setImageLayout(this,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ srcAccessMask,
+ dstAccessMask,
+ srcStageMask,
+ dstStageMask,
+ false);
+
+ // Copy the buffer to the image
+ fCurrentCmdBuffer->copyBufferToImage(this,
egdaniel 2016/04/18 16:46:34 if the surface is linearly tiled should we not jus
jvanverth1 2016/04/19 17:14:27 That would copy the data from the GPU to the CPU,
egdaniel 2016/04/19 17:22:18 unless it is cached :), but we can punt on this fo
+ vkBuffer,
+ vkTex,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ 1,
+ &region);
+
+ // Submit the current command buffer to the Queue
+ this->submitCommandBuffer(kSkip_SyncQueue);
+ }
+
+ if (success) {
+ vkTex->texturePriv().dirtyMipMaps(true);
+ return true;
+ }
+
+ return false;
+}
+
bool GrVkGpu::uploadTexData(GrVkTexture* tex,
int left, int top, int width, int height,
GrPixelConfig dataConfig,
« src/gpu/GrBatchAtlas.cpp ('K') | « src/gpu/vk/GrVkGpu.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698