Re-land "Perform Vulkan resets in a background thread"
Bug: skia:
Change-Id: I1c7ec365a370137ca64d9091cb60e6430c3f1c28
Reviewed-on: https://skia-review.googlesource.com/c/177069
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/vk/GrVkCommandPool.cpp b/src/gpu/vk/GrVkCommandPool.cpp
new file mode 100644
index 0000000..9d7c17e
--- /dev/null
+++ b/src/gpu/vk/GrVkCommandPool.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrVkCommandPool.h"
+
+#include "GrContextPriv.h"
+#include "GrVkCommandBuffer.h"
+#include "GrVkGpu.h"
+
+GrVkCommandPool* GrVkCommandPool::Create(const GrVkGpu* gpu) {
+ const VkCommandPoolCreateInfo cmdPoolInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
+ nullptr, // pNext
+ VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
+ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // CmdPoolCreateFlags
+ gpu->queueIndex(), // queueFamilyIndex
+ };
+ VkCommandPool pool;
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateCommandPool(gpu->device(), &cmdPoolInfo,
+ nullptr, &pool));
+ return new GrVkCommandPool(gpu, pool);
+}
+
+GrVkCommandPool::GrVkCommandPool(const GrVkGpu* gpu, VkCommandPool commandPool)
+ : fCommandPool(commandPool) {
+ fPrimaryCommandBuffer = GrVkPrimaryCommandBuffer::Create(gpu, this);
+}
+
+GrVkSecondaryCommandBuffer* GrVkCommandPool::findOrCreateSecondaryCommandBuffer(GrVkGpu* gpu) {
+ if (fAvailableSecondaryBuffers.count()) {
+ GrVkSecondaryCommandBuffer* result = fAvailableSecondaryBuffers.back();
+ fAvailableSecondaryBuffers.pop_back();
+ return result;
+ }
+ return GrVkSecondaryCommandBuffer::Create(gpu, this);
+}
+
+void GrVkCommandPool::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer) {
+ SkASSERT(buffer->commandPool() == this);
+ fAvailableSecondaryBuffers.push_back(buffer);
+}
+
+void GrVkCommandPool::close() {
+ fOpen = false;
+}
+
+void GrVkCommandPool::reset(GrVkGpu* gpu) {
+ SkASSERT(!fOpen);
+ fOpen = true;
+ fPrimaryCommandBuffer->recycleSecondaryCommandBuffers();
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), ResetCommandPool(gpu->device(), fCommandPool, 0));
+}
+
+void GrVkCommandPool::releaseResources(GrVkGpu* gpu) {
+ SkASSERT(!fOpen);
+ fPrimaryCommandBuffer->releaseResources(gpu);
+ for (GrVkSecondaryCommandBuffer* buffer : fAvailableSecondaryBuffers) {
+ buffer->releaseResources(gpu);
+ }
+}
+
+void GrVkCommandPool::abandonGPUData() const {
+ fPrimaryCommandBuffer->unrefAndAbandon();
+ for (GrVkSecondaryCommandBuffer* buffer : fAvailableSecondaryBuffers) {
+ SkASSERT(buffer->unique());
+ buffer->unrefAndAbandon();
+ }
+}
+
+void GrVkCommandPool::freeGPUData(GrVkGpu* gpu) const {
+ fPrimaryCommandBuffer->unref(gpu);
+ for (GrVkSecondaryCommandBuffer* buffer : fAvailableSecondaryBuffers) {
+ SkASSERT(buffer->unique());
+ buffer->unref(gpu);
+ }
+ if (fCommandPool != VK_NULL_HANDLE) {
+ GR_VK_CALL(gpu->vkInterface(),
+ DestroyCommandPool(gpu->device(), fCommandPool, nullptr));
+ }
+}