Index: src/gpu/vk/GrVkMemory.cpp |
diff --git a/src/gpu/vk/GrVkMemory.cpp b/src/gpu/vk/GrVkMemory.cpp |
index 48bea9c67ef762774e0ca1a968ae2b6656d4506c..98b2f89e243a0964228fd54f3fba9e0f51b6b0cc 100644 |
--- a/src/gpu/vk/GrVkMemory.cpp |
+++ b/src/gpu/vk/GrVkMemory.cpp |
@@ -10,13 +10,12 @@ |
#include "GrVkGpu.h" |
#include "GrVkUtil.h" |
-static bool get_valid_memory_type_index(VkPhysicalDeviceMemoryProperties physDevMemProps, |
+static bool get_valid_memory_type_index(const VkPhysicalDeviceMemoryProperties& physDevMemProps, |
uint32_t typeBits, |
VkMemoryPropertyFlags requestedMemFlags, |
uint32_t* typeIndex) { |
- uint32_t checkBit = 1; |
- for (uint32_t i = 0; i < 32; ++i) { |
- if (typeBits & checkBit) { |
+ for (uint32_t i = 0; i < physDevMemProps.memoryTypeCount; ++i) { |
+ if (typeBits & (1 << i)) { |
uint32_t supportedFlags = physDevMemProps.memoryTypes[i].propertyFlags & |
requestedMemFlags; |
if (supportedFlags == requestedMemFlags) { |
@@ -24,7 +23,6 @@ static bool get_valid_memory_type_index(VkPhysicalDeviceMemoryProperties physDev |
return true; |
} |
} |
- checkBit <<= 1; |
} |
return false; |
} |
@@ -57,21 +55,32 @@ bool GrVkMemory::AllocAndBindBufferMemory(const GrVkGpu* gpu, |
VkMemoryRequirements memReqs; |
GR_VK_CALL(iface, GetBufferMemoryRequirements(device, buffer, &memReqs)); |
- 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, |
- desiredMemProps, |
- &typeIndex)) { |
- // this memory type should always be available |
- SkASSERT_RELEASE(get_valid_memory_type_index(gpu->physicalDeviceMemoryProperties(), |
+ const VkPhysicalDeviceMemoryProperties& phDevMemProps = gpu->physicalDeviceMemoryProperties(); |
+ if (dynamic) { |
+ // try to get cached and ideally non-coherent memory first |
+ if (!get_valid_memory_type_index(phDevMemProps, |
+ memReqs.memoryTypeBits, |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
+ VK_MEMORY_PROPERTY_HOST_CACHED_BIT, |
+ &typeIndex)) { |
+ // some sort of host-visible memory type should always be available for dynamic buffers |
+ SkASSERT_RELEASE(get_valid_memory_type_index(phDevMemProps, |
+ memReqs.memoryTypeBits, |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, |
+ &typeIndex)); |
+ } |
+ |
+ VkMemoryPropertyFlags mpf = phDevMemProps.memoryTypes[typeIndex].propertyFlags; |
+ alloc->fFlags = mpf & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ? 0x0 |
+ : GrVkAlloc::kNoncoherent_Flag; |
+ } else { |
+ // device-local memory should always be available for static buffers |
+ SkASSERT_RELEASE(get_valid_memory_type_index(phDevMemProps, |
memReqs.memoryTypeBits, |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, |
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, |
&typeIndex)); |
+ alloc->fFlags = 0x0; |
} |
GrVkHeap* heap = gpu->getHeap(buffer_type_to_heap(type)); |
@@ -81,7 +90,7 @@ bool GrVkMemory::AllocAndBindBufferMemory(const GrVkGpu* gpu, |
return false; |
} |
- // Bind Memory to device |
+ // Bind buffer |
VkResult err = GR_VK_CALL(iface, BindBufferMemory(device, buffer, |
alloc->fMemory, alloc->fOffset)); |
if (err) { |
@@ -122,25 +131,27 @@ bool GrVkMemory::AllocAndBindImageMemory(const GrVkGpu* gpu, |
uint32_t typeIndex = 0; |
GrVkHeap* heap; |
+ const VkPhysicalDeviceMemoryProperties& phDevMemProps = gpu->physicalDeviceMemoryProperties(); |
if (linearTiling) { |
VkMemoryPropertyFlags desiredMemProps = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT; |
- if (!get_valid_memory_type_index(gpu->physicalDeviceMemoryProperties(), |
+ if (!get_valid_memory_type_index(phDevMemProps, |
memReqs.memoryTypeBits, |
desiredMemProps, |
&typeIndex)) { |
- // this memory type should always be available |
- SkASSERT_RELEASE(get_valid_memory_type_index(gpu->physicalDeviceMemoryProperties(), |
+ // some sort of host-visible memory type should always be available |
+ SkASSERT_RELEASE(get_valid_memory_type_index(phDevMemProps, |
memReqs.memoryTypeBits, |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, |
&typeIndex)); |
} |
heap = gpu->getHeap(GrVkGpu::kLinearImage_Heap); |
+ VkMemoryPropertyFlags mpf = phDevMemProps.memoryTypes[typeIndex].propertyFlags; |
+ alloc->fFlags = mpf & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ? 0x0 |
+ : GrVkAlloc::kNoncoherent_Flag; |
} else { |
// this memory type should always be available |
- SkASSERT_RELEASE(get_valid_memory_type_index(gpu->physicalDeviceMemoryProperties(), |
+ SkASSERT_RELEASE(get_valid_memory_type_index(phDevMemProps, |
memReqs.memoryTypeBits, |
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, |
&typeIndex)); |
@@ -149,6 +160,7 @@ bool GrVkMemory::AllocAndBindImageMemory(const GrVkGpu* gpu, |
} else { |
heap = gpu->getHeap(GrVkGpu::kOptimalImage_Heap); |
} |
+ alloc->fFlags = 0x0; |
} |
if (!heap->alloc(memReqs.size, memReqs.alignment, typeIndex, alloc)) { |
@@ -156,7 +168,7 @@ bool GrVkMemory::AllocAndBindImageMemory(const GrVkGpu* gpu, |
return false; |
} |
- // Bind Memory to device |
+ // Bind image |
VkResult err = GR_VK_CALL(iface, BindImageMemory(device, image, |
alloc->fMemory, alloc->fOffset)); |
if (err) { |
@@ -244,6 +256,32 @@ VkAccessFlags GrVkMemory::LayoutToSrcAccessMask(const VkImageLayout layout) { |
return flags; |
} |
+void GrVkMemory::FlushMappedAlloc(const GrVkGpu* gpu, const GrVkAlloc& alloc) { |
+ if (alloc.fFlags & GrVkAlloc::kNoncoherent_Flag) { |
+ VkMappedMemoryRange mappedMemoryRange; |
+ memset(&mappedMemoryRange, 0, sizeof(VkMappedMemoryRange)); |
+ mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
+ mappedMemoryRange.memory = alloc.fMemory; |
+ mappedMemoryRange.offset = alloc.fOffset; |
+ mappedMemoryRange.size = alloc.fSize; |
+ GR_VK_CALL(gpu->vkInterface(), FlushMappedMemoryRanges(gpu->device(), |
+ 1, &mappedMemoryRange)); |
+ } |
+} |
+ |
+void GrVkMemory::InvalidateMappedAlloc(const GrVkGpu* gpu, const GrVkAlloc& alloc) { |
+ if (alloc.fFlags & GrVkAlloc::kNoncoherent_Flag) { |
+ VkMappedMemoryRange mappedMemoryRange; |
+ memset(&mappedMemoryRange, 0, sizeof(VkMappedMemoryRange)); |
+ mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
+ mappedMemoryRange.memory = alloc.fMemory; |
+ mappedMemoryRange.offset = alloc.fOffset; |
+ mappedMemoryRange.size = alloc.fSize; |
+ GR_VK_CALL(gpu->vkInterface(), InvalidateMappedMemoryRanges(gpu->device(), |
+ 1, &mappedMemoryRange)); |
+ } |
+} |
+ |
bool GrVkFreeListAlloc::alloc(VkDeviceSize requestedSize, |
VkDeviceSize* allocOffset, VkDeviceSize* allocSize) { |
VkDeviceSize alignedSize = align_size(requestedSize, fAlignment); |