Skip to content

Commit

Permalink
vulkan: fix readPixels selectMemory (#7084)
Browse files Browse the repository at this point in the history
readPixels requests staging memory to be host-visible/coherent/cached.
But "cached" is not supported on Mali (Pixel 6pro).  We make it a
preferrable but optional bit.
  • Loading branch information
poweifeng committed Aug 17, 2023
1 parent 69f78db commit 6c0db37
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
3 changes: 1 addition & 2 deletions filament/backend/src/vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ struct VulkanContext {
}
flags >>= 1;
}
ASSERT_POSTCONDITION(false, "Unable to find a memory type that meets requirements.");
return (uint32_t) ~0ul;
return (uint32_t) VK_MAX_MEMORY_TYPES;
}

inline VkFormat getDepthFormat() const {
Expand Down
22 changes: 19 additions & 3 deletions filament/backend/src/vulkan/VulkanReadPixels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,28 @@ void VulkanReadPixels::run(VulkanRenderTarget const* srcTarget, uint32_t const x
VkMemoryRequirements memReqs;
VkDeviceMemory stagingMemory;
vkGetImageMemoryRequirements(device, stagingImage, &memReqs);

uint32_t memoryTypeIndex = selectMemoryFunc(memReqs.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT);

// If VK_MEMORY_PROPERTY_HOST_CACHED_BIT is not supported, we try only
// HOST_VISIBLE+HOST_COHERENT. HOST_CACHED helps a lot with readpixels performance.
if (memoryTypeIndex >= VK_MAX_MEMORY_TYPES) {
memoryTypeIndex = selectMemoryFunc(memReqs.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
utils::slog.w
<< "readPixels is slow because VK_MEMORY_PROPERTY_HOST_CACHED_BIT is not available"
<< utils::io::endl;
}

ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES,
"VulkanReadPixels: unable to find a memory type that meets requirements.");

VkMemoryAllocateInfo const allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = memReqs.size,
.memoryTypeIndex = selectMemoryFunc(memReqs.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT),
.memoryTypeIndex = memoryTypeIndex,
};

vkAllocateMemory(device, &allocInfo, VKALLOC, &stagingMemory);
Expand Down
10 changes: 8 additions & 2 deletions filament/backend/src/vulkan/VulkanTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,17 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
// Allocate memory for the VkImage and bind it.
VkMemoryRequirements memReqs = {};
vkGetImageMemoryRequirements(mDevice, mTextureImage, &memReqs);

uint32_t memoryTypeIndex
= context.selectMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES,
"VulkanTexture: unable to find a memory type that meets requirements.");

VkMemoryAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = memReqs.size,
.memoryTypeIndex = context.selectMemoryType(memReqs.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.memoryTypeIndex = memoryTypeIndex,
};
error = vkAllocateMemory(mDevice, &allocInfo, nullptr, &mTextureImageMemory);
ASSERT_POSTCONDITION(!error, "Unable to allocate image memory.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,17 @@ std::tuple<VkImage, VkDeviceMemory> createImageAndMemory(VulkanContext const& co
VkDeviceMemory imageMemory;
VkMemoryRequirements memReqs;
vkGetImageMemoryRequirements(device, image, &memReqs);

uint32_t memoryTypeIndex
= context.selectMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES,
"VulkanPlatformSwapChainImpl: unable to find a memory type that meets requirements.");

VkMemoryAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = memReqs.size,
.memoryTypeIndex
= context.selectMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
.memoryTypeIndex = memoryTypeIndex,
};
result = vkAllocateMemory(device, &allocInfo, nullptr, &imageMemory);
ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to allocate image memory.");
Expand Down

0 comments on commit 6c0db37

Please sign in to comment.