aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-08-25 11:55:50 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-25 17:03:07 +0000
commit6888c0d40c35a8f09e40a26d8ebd0053ce2faf66 (patch)
treeb74cf1ef190e5afe95f0f14041ea46dbeb1d83c1
parentddaae009e503480275ff2df429c109837c04812c (diff)
Add support for vkCmdCopyBuffer
This is then used when need to update GPU only buffers with data of size greater than 65536. We create a temporary transfer buffer and then copy that buffer into our GPU buffer. Bug: skia: Change-Id: I4bb9cb660f2ac1ccbbd1b508bb4ca6876342136f Reviewed-on: https://skia-review.googlesource.com/38725 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r--src/gpu/vk/GrVkBuffer.cpp18
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp27
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h6
-rw-r--r--src/gpu/vk/GrVkGpu.cpp13
-rw-r--r--src/gpu/vk/GrVkGpu.h2
-rw-r--r--tests/TessellatingPathRendererTests.cpp5
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, &copyRegion);
+}
+
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