Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions impeller/renderer/backend/vulkan/allocator_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,32 @@ ISize AllocatorVK::GetMaxTextureSizeSupported() const {
return max_texture_size_;
}

int32_t AllocatorVK::FindMemoryTypeIndex(
uint32_t memory_type_bits_requirement,
vk::PhysicalDeviceMemoryProperties& memory_properties) {
int32_t type_index = -1;
vk::MemoryPropertyFlagBits required_properties =
vk::MemoryPropertyFlagBits::eDeviceLocal;

const uint32_t memory_count = memory_properties.memoryTypeCount;
for (uint32_t memory_index = 0; memory_index < memory_count; ++memory_index) {
const uint32_t memory_type_bits = (1 << memory_index);
const bool is_required_memory_type =
memory_type_bits_requirement & memory_type_bits;

const auto properties =
memory_properties.memoryTypes[memory_index].propertyFlags;
const bool has_required_properties =
(properties & required_properties) == required_properties;

if (is_required_memory_type && has_required_properties) {
return static_cast<int32_t>(memory_index);
}
}

return type_index;
}

static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(
PixelFormat format,
TextureUsageMask usage,
Expand Down
11 changes: 8 additions & 3 deletions impeller/renderer/backend/vulkan/allocator_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_ALLOCATOR_VK_H_
#define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_ALLOCATOR_VK_H_

#include "flutter/fml/macros.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "impeller/core/allocator.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
#include "impeller/renderer/backend/vulkan/device_holder_vk.h"
#include "impeller/renderer/backend/vulkan/vk.h"

#include <array>
#include <cstdint>
#include <memory>

Expand All @@ -27,6 +24,14 @@ class AllocatorVK final : public Allocator {
// Visible for testing
size_t DebugGetHeapUsage() const;

/// @brief Select a matching memory type for the given
/// [memory_type_bits_requirement], or -1 if none is found.
///
/// This only returns memory types with deviceLocal allocations.
static int32_t FindMemoryTypeIndex(
uint32_t memory_type_bits_requirement,
vk::PhysicalDeviceMemoryProperties& memory_properties);

private:
friend class ContextVK;

Expand Down
38 changes: 38 additions & 0 deletions impeller/renderer/backend/vulkan/allocator_vk_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,44 @@
namespace impeller {
namespace testing {

TEST(AllocatorVKTest, MemoryTypeSelectionSingleHeap) {
vk::PhysicalDeviceMemoryProperties properties;
properties.memoryTypeCount = 1;
properties.memoryHeapCount = 1;
properties.memoryTypes[0].heapIndex = 0;
properties.memoryTypes[0].propertyFlags =
vk::MemoryPropertyFlagBits::eDeviceLocal;
properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;

EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), 0);
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), -1);
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 0);
}

TEST(AllocatorVKTest, MemoryTypeSelectionTwoHeap) {
vk::PhysicalDeviceMemoryProperties properties;
properties.memoryTypeCount = 2;
properties.memoryHeapCount = 2;
properties.memoryTypes[0].heapIndex = 0;
properties.memoryTypes[0].propertyFlags =
vk::MemoryPropertyFlagBits::eHostVisible;
properties.memoryHeaps[0].size = 1024 * 1024 * 1024;
properties.memoryHeaps[0].flags = vk::MemoryHeapFlagBits::eDeviceLocal;

properties.memoryTypes[1].heapIndex = 1;
properties.memoryTypes[1].propertyFlags =
vk::MemoryPropertyFlagBits::eDeviceLocal;
properties.memoryHeaps[1].size = 1024 * 1024 * 1024;
properties.memoryHeaps[1].flags = vk::MemoryHeapFlagBits::eDeviceLocal;

// First fails because this only looks for eDeviceLocal.
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(1, properties), -1);
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(2, properties), 1);
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(3, properties), 1);
EXPECT_EQ(AllocatorVK::FindMemoryTypeIndex(4, properties), -1);
}

#ifdef IMPELLER_DEBUG

TEST(AllocatorVKTest, RecreateSwapchainWhenSizeChanges) {
Expand Down
25 changes: 8 additions & 17 deletions impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.h"

#include "impeller/renderer/backend/vulkan/allocator_vk.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/texture_source_vk.h"
#include "impeller/renderer/backend/vulkan/yuv_conversion_library_vk.h"
Expand Down Expand Up @@ -88,27 +89,16 @@ static vk::UniqueImage CreateVKImageWrapperForAndroidHarwareBuffer(
return std::move(image.value);
}

// Returns -1 if not found.
static int FindMemoryTypeIndex(
const vk::AndroidHardwareBufferPropertiesANDROID& props) {
uint32_t memory_type_bits = props.memoryTypeBits;
int32_t type_index = -1;
for (uint32_t i = 0; memory_type_bits;
memory_type_bits = memory_type_bits >> 0x1, ++i) {
if (memory_type_bits & 0x1) {
type_index = i;
break;
}
}
return type_index;
}

static vk::UniqueDeviceMemory ImportVKDeviceMemoryFromAndroidHarwareBuffer(
const vk::Device& device,
const vk::PhysicalDevice& physical_device,
const vk::Image& image,
struct AHardwareBuffer* hardware_buffer,
const AHBProperties& ahb_props) {
const int memory_type_index = FindMemoryTypeIndex(ahb_props.get());
vk::PhysicalDeviceMemoryProperties memory_properties;
physical_device.getMemoryProperties(&memory_properties);
int memory_type_index = AllocatorVK::FindMemoryTypeIndex(
ahb_props.get().memoryTypeBits, memory_properties);
if (memory_type_index < 0) {
VALIDATION_LOG << "Could not find memory type of external image.";
return {};
Expand Down Expand Up @@ -300,6 +290,7 @@ AHBTextureSourceVK::AHBTextureSourceVK(
}

const auto& device = context->GetDevice();
const auto& physical_device = context->GetPhysicalDevice();

AHBProperties ahb_props;

Expand All @@ -322,7 +313,7 @@ AHBTextureSourceVK::AHBTextureSourceVK(

// Create a device memory allocation to refer to our external image.
auto device_memory = ImportVKDeviceMemoryFromAndroidHarwareBuffer(
device, image.get(), ahb, ahb_props);
device, physical_device, image.get(), ahb, ahb_props);
if (!device_memory) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ class AHBTextureSourceVK final : public TextureSourceVK {
std::shared_ptr<YUVConversionVK> GetYUVConversion() const override;

private:
vk::UniqueDeviceMemory device_memory_;
vk::UniqueImage image_;
vk::UniqueImageView image_view_;
std::shared_ptr<YUVConversionVK> yuv_conversion_;
vk::UniqueDeviceMemory device_memory_ = {};
vk::UniqueImage image_ = {};
vk::UniqueImageView image_view_ = {};
std::shared_ptr<YUVConversionVK> yuv_conversion_ = {};
bool needs_yuv_conversion_ = false;
bool is_valid_ = false;

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/image_external_texture_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ void ImageExternalTextureVK::ProcessFrame(PaintContext& context,

auto texture_source = std::make_shared<impeller::AHBTextureSourceVK>(
impeller_context_, latest_hardware_buffer, hb_desc);
if (!texture_source->IsValid()) {
CloseHardwareBuffer(hardware_buffer);
return;
}

auto texture =
std::make_shared<impeller::TextureVK>(impeller_context_, texture_source);
Expand Down