Add static buffer support
Put resource tracking check in the right place
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2112653002
Review-Url: https://codereview.chromium.org/2112653002
diff --git a/src/gpu/vk/GrVkBuffer.cpp b/src/gpu/vk/GrVkBuffer.cpp
index 1c7c4d0..d28a8cc 100644
--- a/src/gpu/vk/GrVkBuffer.cpp
+++ b/src/gpu/vk/GrVkBuffer.cpp
@@ -29,23 +29,26 @@
bufInfo.flags = 0;
bufInfo.size = desc.fSizeInBytes;
switch (desc.fType) {
- case kVertex_Type:
- bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
- break;
- case kIndex_Type:
- bufInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
- break;
- case kUniform_Type:
- bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
- break;
- case kCopyRead_Type:
- bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
- break;
- case kCopyWrite_Type:
- bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
- break;
-
+ case kVertex_Type:
+ bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ break;
+ case kIndex_Type:
+ bufInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ break;
+ case kUniform_Type:
+ bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ break;
+ case kCopyRead_Type:
+ bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ break;
+ case kCopyWrite_Type:
+ bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+ break;
}
+ if (!desc.fDynamic) {
+ bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+ }
+
bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bufInfo.queueFamilyIndexCount = 0;
bufInfo.pQueueFamilyIndices = nullptr;
@@ -59,6 +62,7 @@
if (!GrVkMemory::AllocAndBindBufferMemory(gpu,
buffer,
desc.fType,
+ desc.fDynamic,
&alloc)) {
return nullptr;
}
@@ -120,6 +124,9 @@
void* GrVkBuffer::vkMap(const GrVkGpu* gpu) {
VALIDATE();
SkASSERT(!this->vkIsMapped());
+ if (!fDesc.fDynamic) {
+ return nullptr;
+ }
if (!fResource->unique()) {
// in use by the command buffer, so we need to create a new one
@@ -141,6 +148,7 @@
void GrVkBuffer::vkUnmap(const GrVkGpu* gpu) {
VALIDATE();
SkASSERT(this->vkIsMapped());
+ SkASSERT(fDesc.fDynamic);
VK_CALL(gpu, UnmapMemory(gpu->device(), this->alloc().fMemory));
@@ -152,7 +160,7 @@
return SkToBool(fMapPtr);
}
-bool GrVkBuffer::vkUpdateData(const GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
+bool GrVkBuffer::vkUpdateData(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
bool* createdNewBuffer) {
SkASSERT(!this->vkIsMapped());
VALIDATE();
@@ -160,6 +168,10 @@
return false;
}
+ if (!fDesc.fDynamic) {
+ return gpu->updateBuffer(this, src, srcSizeInBytes);
+ }
+
if (!fResource->unique()) {
// in use by the command buffer, so we need to create a new one
fResource->unref(gpu);
diff --git a/src/gpu/vk/GrVkBuffer.h b/src/gpu/vk/GrVkBuffer.h
index 0bfbeca..985b586 100644
--- a/src/gpu/vk/GrVkBuffer.h
+++ b/src/gpu/vk/GrVkBuffer.h
@@ -79,7 +79,7 @@
void vkUnmap(const GrVkGpu* gpu);
// If the caller passes in a non null createdNewBuffer, this function will set the bool to true
// if it creates a new VkBuffer to upload the data to.
- bool vkUpdateData(const GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
+ bool vkUpdateData(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
bool* createdNewBuffer = nullptr);
void vkAbandon();
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index 4a469fe..f076c0b 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -475,6 +475,25 @@
copyRegions));
}
+void GrVkPrimaryCommandBuffer::updateBuffer(GrVkGpu* gpu,
+ GrVkBuffer* dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize dataSize,
+ const void* data) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ SkASSERT(0 == (dstOffset & 0x03)); // four byte aligned
+ // TODO: handle larger transfer sizes
+ SkASSERT(dataSize <= 65536);
+ SkASSERT(0 == (dataSize & 0x03)); // four byte aligned
+ this->addResource(dstBuffer->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdUpdateBuffer(fCmdBuffer,
+ dstBuffer->buffer(),
+ dstOffset,
+ dataSize,
+ (const uint32_t*) data));
+}
+
void GrVkPrimaryCommandBuffer::clearColorImage(const GrVkGpu* gpu,
GrVkImage* image,
const VkClearColorValue* color,
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index 87c33c0..95935f0 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -251,6 +251,12 @@
uint32_t copyRegionCount,
const VkBufferImageCopy* copyRegions);
+ void updateBuffer(GrVkGpu* gpu,
+ GrVkBuffer* dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize dataSize,
+ const void* data);
+
void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync);
bool finished(const GrVkGpu* gpu) const;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index e5d24fc..ab6761c 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -425,9 +425,9 @@
}
bool GrVkGpu::uploadTexDataOptimal(GrVkTexture* tex,
- int left, int top, int width, int height,
- GrPixelConfig dataConfig,
- const SkTArray<GrMipLevel>& texels) {
+ int left, int top, int width, int height,
+ GrPixelConfig dataConfig,
+ const SkTArray<GrMipLevel>& texels) {
SkASSERT(!tex->isLinearTiled());
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
SkASSERT(1 == texels.count() ||
@@ -555,10 +555,6 @@
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
regions.count(),
regions.begin());
-
- // Submit the current command buffer to the Queue
- this->submitCommandBuffer(kSkip_SyncQueue);
-
transferBuffer->unref();
return true;
@@ -661,6 +657,16 @@
////////////////////////////////////////////////////////////////////////////////
+bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src, size_t srcSizeInBytes) {
+
+ // Update the buffer
+ fCurrentCmdBuffer->updateBuffer(this, buffer, 0, srcSizeInBytes, src);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
static GrSurfaceOrigin resolve_origin(GrSurfaceOrigin origin) {
// By default, all textures in Vk use TopLeft
if (kDefault_GrSurfaceOrigin == origin) {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 011189a..3373abd 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -125,6 +125,8 @@
void generateMipmap(GrVkTexture* tex) const;
+ bool updateBuffer(GrVkBuffer* buffer, const void* src, size_t srcSizeInBytes);
+
// Heaps
enum Heap {
kLinearImage_Heap = 0,
diff --git a/src/gpu/vk/GrVkMemory.cpp b/src/gpu/vk/GrVkMemory.cpp
index e411d2d..1983db5 100644
--- a/src/gpu/vk/GrVkMemory.cpp
+++ b/src/gpu/vk/GrVkMemory.cpp
@@ -49,6 +49,7 @@
bool GrVkMemory::AllocAndBindBufferMemory(const GrVkGpu* gpu,
VkBuffer buffer,
GrVkBuffer::Type type,
+ bool dynamic,
GrVkAlloc* alloc) {
const GrVkInterface* iface = gpu->vkInterface();
VkDevice device = gpu->device();
@@ -56,9 +57,10 @@
VkMemoryRequirements memReqs;
GR_VK_CALL(iface, GetBufferMemoryRequirements(device, buffer, &memReqs));
- VkMemoryPropertyFlags desiredMemProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
- VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+ VkMemoryPropertyFlags desiredMemProps = dynamic ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
+ VK_MEMORY_PROPERTY_HOST_CACHED_BIT
+ : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
uint32_t typeIndex = 0;
if (!get_valid_memory_type_index(gpu->physicalDeviceMemoryProperties(),
memReqs.memoryTypeBits,
diff --git a/src/gpu/vk/GrVkMemory.h b/src/gpu/vk/GrVkMemory.h
index 44c8286..2b9feda 100644
--- a/src/gpu/vk/GrVkMemory.h
+++ b/src/gpu/vk/GrVkMemory.h
@@ -24,6 +24,7 @@
bool AllocAndBindBufferMemory(const GrVkGpu* gpu,
VkBuffer buffer,
GrVkBuffer::Type type,
+ bool dynamic,
GrVkAlloc* alloc);
void FreeBufferMemory(const GrVkGpu* gpu, GrVkBuffer::Type type, const GrVkAlloc& alloc);
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.cpp b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
index 13b363f..9fa6d6d 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.cpp
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
@@ -251,7 +251,7 @@
}
};
-bool GrVkPipelineStateDataManager::uploadUniformBuffers(const GrVkGpu* gpu,
+bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
GrVkUniformBuffer* vertexBuffer,
GrVkUniformBuffer* fragmentBuffer) const {
bool updatedBuffer = false;
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.h b/src/gpu/vk/GrVkPipelineStateDataManager.h
index c22e779..eb7176c 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.h
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.h
@@ -50,7 +50,7 @@
// Returns true if either the vertex or fragment buffer needed to generate a new underlying
// VkBuffer object in order upload data. If true is returned, this is a signal to the caller
// that they will need to update the descriptor set that is using these buffers.
- bool uploadUniformBuffers(const GrVkGpu* gpu,
+ bool uploadUniformBuffers(GrVkGpu* gpu,
GrVkUniformBuffer* vertexBuffer,
GrVkUniformBuffer* fragmentBuffer) const;
private:
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 31d5568..4f6c792 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -261,10 +261,6 @@
fPipelineStateCache->release();
-#ifdef SK_TRACE_VK_RESOURCES
- SkASSERT(0 == GrVkResource::fTrace.count());
-#endif
-
GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineCache(fGpu->device(), fPipelineCache, nullptr));
fPipelineCache = VK_NULL_HANDLE;
@@ -275,6 +271,10 @@
fUniformDescLayout = VK_NULL_HANDLE;
}
fUniformDescPool->unref(fGpu);
+
+#ifdef SK_TRACE_VK_RESOURCES
+ SkASSERT(0 == GrVkResource::fTrace.count());
+#endif
}
void GrVkResourceProvider::abandonResources() {
@@ -300,13 +300,14 @@
fPipelineStateCache->abandon();
-#ifdef SK_TRACE_VK_RESOURCES
- SkASSERT(0 == GrVkResource::fTrace.count());
-#endif
fPipelineCache = VK_NULL_HANDLE;
fUniformDescLayout = VK_NULL_HANDLE;
fUniformDescPool->unrefAndAbandon();
+
+#ifdef SK_TRACE_VK_RESOURCES
+ SkASSERT(0 == GrVkResource::fTrace.count());
+#endif
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/vk/GrVkTransferBuffer.cpp b/src/gpu/vk/GrVkTransferBuffer.cpp
index 4cf5c1b..f291dcd 100644
--- a/src/gpu/vk/GrVkTransferBuffer.cpp
+++ b/src/gpu/vk/GrVkTransferBuffer.cpp
@@ -12,7 +12,7 @@
GrVkTransferBuffer* GrVkTransferBuffer::Create(GrVkGpu* gpu, size_t size, GrVkBuffer::Type type) {
GrVkBuffer::Desc desc;
- desc.fDynamic = false;
+ desc.fDynamic = true;
SkASSERT(GrVkBuffer::kCopyRead_Type == type || GrVkBuffer::kCopyWrite_Type == type);
desc.fType = type;
desc.fSizeInBytes = size;
diff --git a/src/gpu/vk/GrVkUniformBuffer.h b/src/gpu/vk/GrVkUniformBuffer.h
index 37ede72..bfaf240 100644
--- a/src/gpu/vk/GrVkUniformBuffer.h
+++ b/src/gpu/vk/GrVkUniformBuffer.h
@@ -25,7 +25,7 @@
}
// The output variable createdNewBuffer must be set to true if a new VkBuffer is created in
// order to upload the data
- bool updateData(const GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
+ bool updateData(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
bool* createdNewBuffer) {
return this->vkUpdateData(gpu, src, srcSizeInBytes, createdNewBuffer);
}