diff options
-rw-r--r-- | src/gpu/vk/GrVkBuffer.cpp | 18 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.cpp | 27 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCommandBuffer.h | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.cpp | 13 | ||||
-rw-r--r-- | src/gpu/vk/GrVkGpu.h | 2 | ||||
-rw-r--r-- | tests/TessellatingPathRendererTests.cpp | 5 |
6 files changed, 64 insertions, 7 deletions
diff --git a/src/gpu/vk/GrVkBuffer.cpp b/src/gpu/vk/GrVkBuffer.cpp index 9926ec4ad0..b2af229de3 100644 --- a/src/gpu/vk/GrVkBuffer.cpp +++ b/src/gpu/vk/GrVkBuffer.cpp @@ -8,6 +8,7 @@ #include "GrVkBuffer.h" #include "GrVkGpu.h" #include "GrVkMemory.h" +#include "GrVkTransferBuffer.h" #include "GrVkUtil.h" #define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) @@ -192,7 +193,22 @@ void GrVkBuffer::internalUnmap(GrVkGpu* gpu, size_t size) { VK_CALL(gpu, UnmapMemory(gpu->device(), this->alloc().fMemory)); fMapPtr = nullptr; } else { - gpu->updateBuffer(this, fMapPtr, this->offset(), size); + if (size <= 65536) { + gpu->updateBuffer(this, fMapPtr, this->offset(), size); + } else { + GrVkTransferBuffer* transferBuffer = + GrVkTransferBuffer::Create(gpu, size, GrVkBuffer::kCopyRead_Type); + if(!transferBuffer) { + return; + } + + char* buffer = (char*) transferBuffer->map(); + memcpy (buffer, fMapPtr, size); + transferBuffer->unmap(); + + gpu->copyBuffer(transferBuffer, this, 0, this->offset(), size); + transferBuffer->unref(); + } this->addMemoryBarrier(gpu, VK_ACCESS_TRANSFER_WRITE_BIT, buffer_type_to_access_flags(fDesc.fType), diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp index 1f124a6e04..c44d12128e 100644 --- a/src/gpu/vk/GrVkCommandBuffer.cpp +++ b/src/gpu/vk/GrVkCommandBuffer.cpp @@ -637,6 +637,33 @@ void GrVkPrimaryCommandBuffer::copyBufferToImage(const GrVkGpu* gpu, copyRegions)); } + +void GrVkPrimaryCommandBuffer::copyBuffer(GrVkGpu* gpu, + GrVkBuffer* srcBuffer, + GrVkBuffer* dstBuffer, + uint32_t regionCount, + const VkBufferCopy* regions) { + SkASSERT(fIsActive); + SkASSERT(!fActiveRenderPass); +#ifdef SK_DEBUG + for (uint32_t i = 0; i < regionCount; ++i) { + const VkBufferCopy& region = regions[i]; + SkASSERT(region.size > 0); + SkASSERT(region.srcOffset < srcBuffer->size()); + SkASSERT(region.dstOffset < dstBuffer->size()); + SkASSERT(region.srcOffset + region.size <= srcBuffer->size()); + SkASSERT(region.dstOffset + region.size <= dstBuffer->size()); + } +#endif + this->addResource(srcBuffer->resource()); + this->addResource(dstBuffer->resource()); + GR_VK_CALL(gpu->vkInterface(), CmdCopyBuffer(fCmdBuffer, + srcBuffer->buffer(), + dstBuffer->buffer(), + regionCount, + regions)); +} + void GrVkPrimaryCommandBuffer::updateBuffer(GrVkGpu* gpu, GrVkBuffer* dstBuffer, VkDeviceSize dstOffset, diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h index 548efad8a2..7d16242e6b 100644 --- a/src/gpu/vk/GrVkCommandBuffer.h +++ b/src/gpu/vk/GrVkCommandBuffer.h @@ -250,6 +250,12 @@ public: uint32_t copyRegionCount, const VkBufferImageCopy* copyRegions); + void copyBuffer(GrVkGpu* gpu, + GrVkBuffer* srcBuffer, + GrVkBuffer* dstBuffer, + uint32_t regionCount, + const VkBufferCopy* regions); + void updateBuffer(GrVkGpu* gpu, GrVkBuffer* dstBuffer, VkDeviceSize dstOffset, diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index a36bbe51fb..83d28decb6 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -690,8 +690,9 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex, // allocate buffer to hold our mip data GrVkTransferBuffer* transferBuffer = GrVkTransferBuffer::Create(this, combinedBufferSize, GrVkBuffer::kCopyRead_Type); - if(!transferBuffer) + if(!transferBuffer) { return false; + } char* buffer = (char*) transferBuffer->map(); SkTArray<VkBufferImageCopy> regions(mipLevelCount); @@ -844,9 +845,17 @@ sk_sp<GrTexture> GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted //////////////////////////////////////////////////////////////////////////////// +void GrVkGpu::copyBuffer(GrVkBuffer* srcBuffer, GrVkBuffer* dstBuffer, VkDeviceSize srcOffset, + VkDeviceSize dstOffset, VkDeviceSize size) { + VkBufferCopy copyRegion; + copyRegion.srcOffset = srcOffset; + copyRegion.dstOffset = dstOffset; + copyRegion.size = size; + fCurrentCmdBuffer->copyBuffer(this, srcBuffer, dstBuffer, 1, ©Region); +} + bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size) { - // Update the buffer fCurrentCmdBuffer->updateBuffer(this, buffer, offset, size, src); diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index ad157cac9f..f36ec315fb 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -144,6 +144,8 @@ public: void generateMipmap(GrVkTexture* tex); + void copyBuffer(GrVkBuffer* srcBuffer, GrVkBuffer* dstBuffer, VkDeviceSize srcOffset, + VkDeviceSize dstOffset, VkDeviceSize size); bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size); // Heaps diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index 78704d94b4..0ae5d55bda 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -454,9 +454,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) { test_path(ctx, rtc.get(), create_path_21(), SkMatrix(), GrAAType::kCoverage); test_path(ctx, rtc.get(), create_path_22()); test_path(ctx, rtc.get(), create_path_23()); - // TODO: implement large buffer uploads in VK and remove this check. - if (ctx->contextPriv().getBackend() != kVulkan_GrBackend) { - test_path(ctx, rtc.get(), create_path_24()); - } + test_path(ctx, rtc.get(), create_path_24()); } #endif |