diff options
author | Greg Daniel <egdaniel@google.com> | 2018-05-25 11:02:16 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-25 15:24:42 +0000 |
commit | 26c0e4c1f54759249c2d61b50fb5430bd73793f2 (patch) | |
tree | 42dee870d6db76cc4a532f77914bfbf837918be1 /include | |
parent | e7e6e22912cec1bd59348fd3889c7d8ae7b6bdc4 (diff) |
Create API for GrVkMemoryAllocator and impliment use of AMD VulkanMemoryAllocator on this API.
Bug: skia:
Change-Id: I1e122e1b11ab308c2f83cb98c36c81511f4507d0
Reviewed-on: https://skia-review.googlesource.com/129980
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/gpu/vk/GrVkDefines.h | 76 | ||||
-rw-r--r-- | include/gpu/vk/GrVkMemoryAllocator.h | 89 | ||||
-rw-r--r-- | include/gpu/vk/GrVkTypes.h | 15 |
3 files changed, 176 insertions, 4 deletions
diff --git a/include/gpu/vk/GrVkDefines.h b/include/gpu/vk/GrVkDefines.h index d17300a550..0fd405d55c 100644 --- a/include/gpu/vk/GrVkDefines.h +++ b/include/gpu/vk/GrVkDefines.h @@ -51,6 +51,82 @@ #error "Vulkan header version is too low" #endif +// The AMD VulkanMemoryAllocator needs the objects from this extension to be declared. +#ifndef VK_KHR_get_memory_requirements2 + +#define VK_KHR_get_memory_requirements2 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" + +typedef struct VkBufferMemoryRequirementsInfo2KHR { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferMemoryRequirementsInfo2KHR; + +typedef struct VkImageMemoryRequirementsInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageMemoryRequirementsInfo2KHR; + +typedef struct VkImageSparseMemoryRequirementsInfo2KHR { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageSparseMemoryRequirementsInfo2KHR; + +typedef struct VkMemoryRequirements2KHR { + VkStructureType sType; + void* pNext; + VkMemoryRequirements memoryRequirements; +} VkMemoryRequirements2KHR; + +typedef struct VkSparseImageMemoryRequirements2KHR { + VkStructureType sType; + void* pNext; + VkSparseImageMemoryRequirements memoryRequirements; +} VkSparseImageMemoryRequirements2KHR; + + +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2KHR* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements); + +static constexpr VkStructureType VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = (VkStructureType) 1000146000; +static constexpr VkStructureType VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = (VkStructureType) 1000146001; +static constexpr VkStructureType VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = (VkStructureType) 1000146002; +static constexpr VkStructureType VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = (VkStructureType) 1000146003; +static constexpr VkStructureType VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = (VkStructureType) 1000146004; + +#endif // VK_KHR_get_memory_requirements2 + +// Also needed for VulkanMemoryAllocator +#ifndef VK_KHR_dedicated_allocation + +#define VK_KHR_dedicated_allocation 1 +#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 +#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" + +typedef struct VkMemoryDedicatedRequirementsKHR { + VkStructureType sType; + void* pNext; + VkBool32 prefersDedicatedAllocation; + VkBool32 requiresDedicatedAllocation; +} VkMemoryDedicatedRequirementsKHR; + +typedef struct VkMemoryDedicatedAllocateInfoKHR { + VkStructureType sType; + const void* pNext; + VkImage image; + VkBuffer buffer; +} VkMemoryDedicatedAllocateInfoKHR; + +static constexpr VkStructureType VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = (VkStructureType) 1000127000; +static constexpr VkStructureType VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = (VkStructureType) 1000127001; + +#endif // VK_KHR_dedicated_allocation + #endif #endif diff --git a/include/gpu/vk/GrVkMemoryAllocator.h b/include/gpu/vk/GrVkMemoryAllocator.h new file mode 100644 index 0000000000..0e73586c3b --- /dev/null +++ b/include/gpu/vk/GrVkMemoryAllocator.h @@ -0,0 +1,89 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrVkMemoryAllocator_DEFINED +#define GrVkMemoryAllocator_DEFINED + +#include "SkRefCnt.h" +#include "GrTypes.h" +#include "GrVkDefines.h" +#include "GrVkTypes.h" + +class GrVkMemoryAllocator : public SkRefCnt { +public: + enum class AllocationPropertyFlags { + kNone = 0, + // Allocation will be placed in its own VkDeviceMemory and not suballocated from some larger + // block. + kDedicatedAllocation = 0x1, + // Says that the backing memory can only be accessed by the device. Additionally the device + // may lazily allocate the memory. This cannot be used with buffers that will be host + // visible. Setting this flag does not guarantee that we will allocate memory that respects + // it, but we will try to prefer memory that can respect it. + kLazyAllocation = 0x2, + // The allocation will be mapped immediately and stay mapped until it is destroyed. This + // flag is only valid for buffers which are host visible (i.e. must have a usage other than + // BufferUsage::kGpuOnly). + kPersistentlyMapped = 0x3, + }; + + GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AllocationPropertyFlags); + + enum class BufferUsage { + // Buffers that will only be accessed from the device (large const buffers). Will always be + // in device local memory. + kGpuOnly, + // Buffers that will be accessed on the host and copied to and from a GPU resource (transfer + // buffers). Will always be mappable and coherent memory. + kCpuOnly, + // Buffers that typically will be updated multiple times by the host and read on the gpu + // (e.g. uniform or vertex buffers). Will always be mappable memory, and will prefer to be + // in device local memory. + kCpuWritesGpuReads, + // Buffers which are typically writted to by the GPU and then read on the host. Will always + // be mappable memory, and will prefer coherent and cached memory. + kGpuWritesCpuReads, + }; + + virtual bool allocateMemoryForImage(VkImage image, AllocationPropertyFlags flags, + GrVkBackendMemory*) = 0; + + virtual bool allocateMemoryForBuffer(VkBuffer buffer, BufferUsage usage, + AllocationPropertyFlags flags, GrVkBackendMemory*) = 0; + + // Fills out the passed in GrVkAlloc struct for the passed in GrVkBackendMemory. + virtual void getAllocInfo(const GrVkBackendMemory&, GrVkAlloc*) const = 0; + + // Maps the entire allocation and returns a pointer to the start of the allocation. The + // implementation may map more memory than just the allocation, but the returned pointer must + // point at the start of the memory for the requested allocation. + virtual void* mapMemory(const GrVkBackendMemory&) = 0; + virtual void unmapMemory(const GrVkBackendMemory&) = 0; + + // The following two calls are used for managing non-coherent memory. The offset is relative to + // the start of the allocation and not the underlying VkDeviceMemory. Additionaly the client + // must make sure that the offset + size passed in is less that or equal to the allocation size. + // It is the responsibility of the implementation to make sure all alignment requirements are + // followed. The client should not have to deal with any sort of alignment issues. + virtual void flushMappedMemory(const GrVkBackendMemory&, VkDeviceSize offset, + VkDeviceSize size) = 0; + virtual void invalidateMappedMemory(const GrVkBackendMemory&, VkDeviceSize offset, + VkDeviceSize size)= 0; + + virtual void freeMemory(const GrVkBackendMemory&) = 0; + + // Returns the total amount of memory that is allocated and in use by an allocation for this + // allocator. + virtual uint64_t totalUsedMemory() const = 0; + + // Returns the total amount of memory that is allocated by this allocator. + virtual uint64_t totalAllocatedMemory() const = 0; +}; + +GR_MAKE_BITFIELD_CLASS_OPS(GrVkMemoryAllocator::AllocationPropertyFlags); + +#endif diff --git a/include/gpu/vk/GrVkTypes.h b/include/gpu/vk/GrVkTypes.h index 0f7ff71d2e..2e31250324 100644 --- a/include/gpu/vk/GrVkTypes.h +++ b/include/gpu/vk/GrVkTypes.h @@ -26,6 +26,9 @@ /////////////////////////////////////////////////////////////////////////////// + +typedef intptr_t GrVkBackendMemory; + /** * Types for interacting with Vulkan resources created externally to Skia. GrBackendObjects for * Vulkan textures are really const GrVkImageInfo* @@ -36,6 +39,7 @@ struct GrVkAlloc { , fOffset(0) , fSize(0) , fFlags(0) + , fBackendMemory(0) , fUsesSystemHeap(false) {} GrVkAlloc(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, uint32_t flags) @@ -43,15 +47,18 @@ struct GrVkAlloc { , fOffset(offset) , fSize(size) , fFlags(flags) + , fBackendMemory(0) , fUsesSystemHeap(false) {} - VkDeviceMemory fMemory; // can be VK_NULL_HANDLE iff is an RT and is borrowed - VkDeviceSize fOffset; - VkDeviceSize fSize; // this can be indeterminate iff Tex uses borrow semantics - uint32_t fFlags; + VkDeviceMemory fMemory; // can be VK_NULL_HANDLE iff is an RT and is borrowed + VkDeviceSize fOffset; + VkDeviceSize fSize; // this can be indeterminate iff Tex uses borrow semantics + uint32_t fFlags; + GrVkBackendMemory fBackendMemory; // handle to memory allocated via GrVkMemoryAllocator. enum Flag { kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping + kMappable_Flag = 0x2, // memory is able to be mapped. }; bool operator==(const GrVkAlloc& that) const { |