/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrVkBuffer_DEFINED #define GrVkBuffer_DEFINED #include "GrVkResource.h" #include "vk/GrVkDefines.h" #include "vk/GrVkTypes.h" class GrVkGpu; /** * This class serves as the base of GrVk*Buffer classes. It was written to avoid code * duplication in those classes. */ class GrVkBuffer : public SkNoncopyable { public: virtual ~GrVkBuffer() { // either release or abandon should have been called by the owner of this object. SkASSERT(!fResource); delete [] (unsigned char*)fMapPtr; } VkBuffer buffer() const { return fResource->fBuffer; } const GrVkAlloc& alloc() const { return fResource->fAlloc; } const GrVkRecycledResource* resource() const { return fResource; } size_t size() const { return fDesc.fSizeInBytes; } VkDeviceSize offset() const { return fOffset; } void addMemoryBarrier(const GrVkGpu* gpu, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, bool byRegion) const; enum Type { kVertex_Type, kIndex_Type, kUniform_Type, kTexel_Type, kCopyRead_Type, kCopyWrite_Type, }; protected: struct Desc { size_t fSizeInBytes; Type fType; // vertex buffer, index buffer, etc. bool fDynamic; }; class Resource : public GrVkRecycledResource { public: Resource(VkBuffer buf, const GrVkAlloc& alloc, Type type) : INHERITED(), fBuffer(buf), fAlloc(alloc), fType(type) {} #ifdef SK_TRACE_VK_RESOURCES void dumpInfo() const override { SkDebugf("GrVkBuffer: %d (%d refs)\n", fBuffer, this->getRefCnt()); } #endif VkBuffer fBuffer; GrVkAlloc fAlloc; Type fType; private: void freeGPUData(const GrVkGpu* gpu) const override; void onRecycle(GrVkGpu* gpu) const override { this->unref(gpu); } typedef GrVkRecycledResource INHERITED; }; // convenience routine for raw buffer creation static const Resource* Create(const GrVkGpu* gpu, const Desc& descriptor); GrVkBuffer(const Desc& desc, const GrVkBuffer::Resource* resource) : fDesc(desc), fResource(resource), fOffset(0), fMapPtr(nullptr) { } void* vkMap(GrVkGpu* gpu) { this->internalMap(gpu, fDesc.fSizeInBytes); return fMapPtr; } void vkUnmap(GrVkGpu* gpu) { this->internalUnmap(gpu, this->size()); } // 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(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes, bool* createdNewBuffer = nullptr); void vkAbandon(); void vkRelease(const GrVkGpu* gpu); private: virtual const Resource* createResource(GrVkGpu* gpu, const Desc& descriptor) { return Create(gpu, descriptor); } void internalMap(GrVkGpu* gpu, size_t size, bool* createdNewBuffer = nullptr); void internalUnmap(GrVkGpu* gpu, size_t size); void validate() const; bool vkIsMapped() const; Desc fDesc; const Resource* fResource; VkDeviceSize fOffset; void* fMapPtr; typedef SkNoncopyable INHERITED; }; #endif