Index: src/gpu/vk/GrVkUniformBuffer.cpp |
diff --git a/src/gpu/vk/GrVkUniformBuffer.cpp b/src/gpu/vk/GrVkUniformBuffer.cpp |
index 022e2e33bdd10f978d49d6b622539b74db679d19..c3899b01b9437595f0174d9bc4f18df9e60e4560 100644 |
--- a/src/gpu/vk/GrVkUniformBuffer.cpp |
+++ b/src/gpu/vk/GrVkUniformBuffer.cpp |
@@ -8,24 +8,84 @@ |
#include "GrVkUniformBuffer.h" |
#include "GrVkGpu.h" |
+#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) |
-GrVkUniformBuffer* GrVkUniformBuffer::Create(GrVkGpu* gpu, size_t size, bool dynamic) { |
+GrVkUniformBuffer* GrVkUniformBuffer::Create(GrVkGpu* gpu, size_t size) { |
if (0 == size) { |
return nullptr; |
} |
+ const GrVkResource* resource = nullptr; |
+ if (size <= GrVkUniformBuffer::kStandardSize) { |
+ resource = gpu->resourceProvider().findOrCreateStandardUniformBufferResource(); |
+ } else { |
+ resource = CreateResource(gpu, size); |
+ } |
+ if (!resource) { |
+ return nullptr; |
+ } |
+ |
GrVkBuffer::Desc desc; |
- desc.fDynamic = dynamic; |
+ desc.fDynamic = true; |
desc.fType = GrVkBuffer::kUniform_Type; |
desc.fSizeInBytes = size; |
+ GrVkUniformBuffer* buffer = new GrVkUniformBuffer(gpu, desc, |
+ (const GrVkUniformBuffer::Resource*) resource); |
+ if (!buffer) { |
+ // this will destroy anything we got from the resource provider, |
+ // but this avoids a conditional |
+ resource->unref(gpu); |
+ } |
+ return buffer; |
+} |
- const GrVkBuffer::Resource* bufferResource = GrVkBuffer::Create(gpu, desc); |
- if (!bufferResource) { |
+// We implement our own creation function for special buffer resource type |
+const GrVkResource* GrVkUniformBuffer::CreateResource(GrVkGpu* gpu, size_t size) { |
+ if (0 == size) { |
return nullptr; |
} |
- GrVkUniformBuffer* buffer = new GrVkUniformBuffer(desc, bufferResource); |
- if (!buffer) { |
- bufferResource->unref(gpu); |
+ VkBuffer buffer; |
+ GrVkAlloc alloc; |
+ |
+ // create the buffer object |
+ VkBufferCreateInfo bufInfo; |
+ memset(&bufInfo, 0, sizeof(VkBufferCreateInfo)); |
+ bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
+ bufInfo.flags = 0; |
+ bufInfo.size = size; |
+ bufInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; |
+ bufInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; |
+ bufInfo.queueFamilyIndexCount = 0; |
+ bufInfo.pQueueFamilyIndices = nullptr; |
+ |
+ VkResult err; |
+ err = VK_CALL(gpu, CreateBuffer(gpu->device(), &bufInfo, nullptr, &buffer)); |
+ if (err) { |
+ return nullptr; |
} |
- return buffer; |
-} |
+ |
+ if (!GrVkMemory::AllocAndBindBufferMemory(gpu, |
+ buffer, |
+ kUniform_Type, |
+ true, // dynamic |
+ &alloc)) { |
+ return nullptr; |
+ } |
+ |
+ const GrVkResource* resource = new GrVkUniformBuffer::Resource(buffer, alloc); |
+ if (!resource) { |
+ VK_CALL(gpu, DestroyBuffer(gpu->device(), buffer, nullptr)); |
+ GrVkMemory::FreeBufferMemory(gpu, kUniform_Type, alloc); |
+ return nullptr; |
+ } |
+ |
+ return resource; |
+} |
+ |
+void GrVkUniformBuffer::Resource::onRecycle(GrVkGpu* gpu) const { |
+ if (fAlloc.fSize <= GrVkUniformBuffer::kStandardSize) { |
+ gpu->resourceProvider().recycleStandardUniformBufferResource(this); |
+ } else { |
+ this->unref(gpu); |
+ } |
+} |