diff --git a/include/gpu/vk/GrVkMemoryAllocator.h b/include/gpu/vk/GrVkMemoryAllocator.h index 2679c8ec63..0e8af45e73 100644 --- a/include/gpu/vk/GrVkMemoryAllocator.h +++ b/include/gpu/vk/GrVkMemoryAllocator.h @@ -35,6 +35,7 @@ public: GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AllocationPropertyFlags); enum class BufferUsage { +#ifdef SK_USE_LEGACY_VK_ALLOCATOR_USAGE_NAMES // Buffers that will only be accessed from the device (large const buffers). Will always be // in device local memory. kGpuOnly, @@ -50,6 +51,23 @@ public: // Buffers which are typically writted to by the GPU and then read on the host. Will always // be mappable memory, and will prefer cached memory. kGpuWritesCpuReads, +#else + // Buffers that will only be accessed from the device (large const buffers). Will always be + // in device local memory. + kGpuOnly, + // Buffers that typically will be updated multiple times by the host and read on the gpu + // (e.g. uniform or vertex buffers). CPU writes will generally be sequential in the buffer + // and will try to take advantage of the write-combined nature of the gpu buffers. Thus this + // will always be mappable and coherent memory, and it will prefer to be in device local + // memory. + kCpuWritesGpuReads, + // Buffers that will be accessed on the host and copied to another GPU resource (transfer + // buffers). Will always be mappable and coherent memory. + kTransfersFromCpuToGpu, + // Buffers which are typically writted to by the GPU and then read on the host. Will always + // be mappable memory, and will prefer cached memory. + kTransfersFromGpuToCpu, +#endif }; // DEPRECATED: Use and implement allocateImageMemory instead diff --git a/src/gpu/vk/GrVkAMDMemoryAllocator.cpp b/src/gpu/vk/GrVkAMDMemoryAllocator.cpp index 5bae6fe952..b611322513 100644 --- a/src/gpu/vk/GrVkAMDMemoryAllocator.cpp +++ b/src/gpu/vk/GrVkAMDMemoryAllocator.cpp @@ -146,6 +146,7 @@ VkResult GrVkAMDMemoryAllocator::allocateBufferMemory(VkBuffer buffer, BufferUsa info.pUserData = nullptr; switch (usage) { +#ifdef SK_USE_LEGACY_VK_ALLOCATOR_USAGE_NAMES case BufferUsage::kGpuOnly: info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; info.preferredFlags = 0; @@ -176,6 +177,37 @@ VkResult GrVkAMDMemoryAllocator::allocateBufferMemory(VkBuffer buffer, BufferUsa info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT; break; +#else + case BufferUsage::kGpuOnly: + info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + info.preferredFlags = 0; + break; + case BufferUsage::kCpuWritesGpuReads: + // When doing cpu writes and gpu reads the general rule of thumb is to use coherent + // memory. Though this depends on the fact that we are not doing any cpu reads and the + // cpu writes are sequential. For sparse writes we'd want cpu cached memory, however we + // don't do these types of writes in Skia. + // + // TODO: In the future there may be times where specific types of memory could benefit + // from a coherent and cached memory. Typically these allow for the gpu to read cpu + // writes from the cache without needing to flush the writes throughout the cache. The + // reverse is not true and GPU writes tend to invalidate the cache regardless. Also + // these gpu cache read access are typically lower bandwidth than non-cached memory. + // For now Skia doesn't really have a need or want of this type of memory. But if we + // ever do we could pass in an AllocationPropertyFlag that requests the cached property. + info.requiredFlags = + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + break; + case BufferUsage::kTransfersFromCpuToGpu: + info.requiredFlags = + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + break; + case BufferUsage::kTransfersFromGpuToCpu: + info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + break; +#endif } if (fMustUseCoherentHostVisibleMemory && @@ -198,13 +230,6 @@ VkResult GrVkAMDMemoryAllocator::allocateBufferMemory(VkBuffer buffer, BufferUsa VmaAllocation allocation; VkResult result = vmaAllocateMemoryForBuffer(fAllocator, buffer, &info, &allocation, nullptr); - if (VK_SUCCESS != result) { - if (usage == BufferUsage::kCpuWritesGpuReads) { - // We try again but this time drop the requirement for cached - info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - result = vmaAllocateMemoryForBuffer(fAllocator, buffer, &info, &allocation, nullptr); - } - } if (VK_SUCCESS == result) { *backendMemory = (GrVkBackendMemory)allocation; } diff --git a/src/gpu/vk/GrVkBuffer.cpp b/src/gpu/vk/GrVkBuffer.cpp index ec4a51270f..8b84f27175 100644 --- a/src/gpu/vk/GrVkBuffer.cpp +++ b/src/gpu/vk/GrVkBuffer.cpp @@ -107,11 +107,16 @@ sk_sp GrVkBuffer::Make(GrVkGpu* gpu, break; case GrGpuBufferType::kXferCpuToGpu: bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + // TODO: After done with all the renaming will move this to kTransfersFromCpuToGpu allocUsage = BufferUsage::kCpuWritesGpuReads; break; case GrGpuBufferType::kXferGpuToCpu: bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; +#ifdef SK_USE_LEGACY_VK_ALLOCATOR_USAGE_NAMES allocUsage = BufferUsage::kGpuWritesCpuReads; +#else + allocUsage = BufferUsage::kTransfersFromGpuToCpu; +#endif break; } // We may not always get a mappable buffer for non dynamic access buffers. Thus we set the