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
1 change: 1 addition & 0 deletions impeller/renderer/backend/gles/context_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ ContextGLES::ContextGLES(std::unique_ptr<ProcTableGLES> gl,
.SetSupportsReadFromResolve(false)
.SetSupportsReadFromOnscreenTexture(false)
.SetSupportsDecalTileMode(false)
.SetSupportsMemorylessTextures(false)
.Build();
}

Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/metal/context_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ static bool DeviceSupportsComputeSubgroups(id<MTLDevice> device) {
.SetSupportsComputeSubgroups(DeviceSupportsComputeSubgroups(device))
.SetSupportsReadFromResolve(true)
.SetSupportsReadFromOnscreenTexture(true)
.SetSupportsMemorylessTextures(true)
.Build();
}

Expand Down
62 changes: 44 additions & 18 deletions impeller/renderer/backend/vulkan/allocator_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
const std::shared_ptr<DeviceHolder>& device_holder,
const vk::Instance& instance,
PFN_vkGetInstanceProcAddr get_instance_proc_address,
PFN_vkGetDeviceProcAddr get_device_proc_address)
PFN_vkGetDeviceProcAddr get_device_proc_address,
const CapabilitiesVK& capabilities)
: context_(std::move(context)), device_holder_(device_holder) {
vk_ = fml::MakeRefCounted<vulkan::VulkanProcTable>(get_instance_proc_address);

Expand Down Expand Up @@ -91,6 +92,7 @@ AllocatorVK::AllocatorVK(std::weak_ptr<Context> context,
return;
}
allocator_ = allocator;
supports_memoryless_textures_ = capabilities.SupportsMemorylessTextures();
is_valid_ = true;
}

Expand All @@ -110,17 +112,21 @@ ISize AllocatorVK::GetMaxTextureSizeSupported() const {
return max_texture_size_;
}

static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(PixelFormat format,
TextureUsageMask usage,
StorageMode mode) {
static constexpr vk::ImageUsageFlags ToVKImageUsageFlags(
PixelFormat format,
TextureUsageMask usage,
StorageMode mode,
bool supports_memoryless_textures) {
vk::ImageUsageFlags vk_usage;

switch (mode) {
case StorageMode::kHostVisible:
case StorageMode::kDevicePrivate:
break;
case StorageMode::kDeviceTransient:
vk_usage |= vk::ImageUsageFlagBits::eTransientAttachment;
if (supports_memoryless_textures) {
vk_usage |= vk::ImageUsageFlagBits::eTransientAttachment;
}
break;
}

Expand Down Expand Up @@ -168,7 +174,25 @@ static constexpr VmaMemoryUsage ToVMAMemoryUsage() {
return VMA_MEMORY_USAGE_AUTO;
}

static constexpr VkMemoryPropertyFlags ToVKMemoryPropertyFlags(
static constexpr VkMemoryPropertyFlags ToVKTextureMemoryPropertyFlags(
StorageMode mode,
bool supports_memoryless_textures) {
switch (mode) {
case StorageMode::kHostVisible:
return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
case StorageMode::kDevicePrivate:
return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
case StorageMode::kDeviceTransient:
if (supports_memoryless_textures) {
return VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT |
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
FML_UNREACHABLE();
}

static constexpr VkMemoryPropertyFlags ToVKBufferMemoryPropertyFlags(
StorageMode mode) {
switch (mode) {
case StorageMode::kHostVisible:
Expand Down Expand Up @@ -196,9 +220,6 @@ static VmaAllocationCreateFlags ToVmaAllocationCreateFlags(StorageMode mode,
}
return flags;
case StorageMode::kDevicePrivate:
if (is_texture) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not use VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT until we have a case where it performs better

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought Angle did that for > 4MB allocations though. Perhaps just start off with that assumption, but for non-render targets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets follow up on this one in #43325 ?

If we don't remove this bit we'll have the same performance issues as dedicated allocations don't go into the pool.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
}
return flags;
case StorageMode::kDeviceTransient:
return flags;
Expand All @@ -210,7 +231,8 @@ class AllocatedTextureSourceVK final : public TextureSourceVK {
public:
AllocatedTextureSourceVK(const TextureDescriptor& desc,
VmaAllocator allocator,
vk::Device device)
vk::Device device,
bool supports_memoryless_textures)
: TextureSourceVK(desc) {
vk::ImageCreateInfo image_info;
image_info.flags = ToVKImageCreateFlags(desc.type);
Expand All @@ -227,13 +249,15 @@ class AllocatedTextureSourceVK final : public TextureSourceVK {
image_info.tiling = vk::ImageTiling::eOptimal;
image_info.initialLayout = vk::ImageLayout::eUndefined;
image_info.usage =
ToVKImageUsageFlags(desc.format, desc.usage, desc.storage_mode);
ToVKImageUsageFlags(desc.format, desc.usage, desc.storage_mode,
supports_memoryless_textures);
image_info.sharingMode = vk::SharingMode::eExclusive;

VmaAllocationCreateInfo alloc_nfo = {};

alloc_nfo.usage = ToVMAMemoryUsage();
alloc_nfo.preferredFlags = ToVKMemoryPropertyFlags(desc.storage_mode);
alloc_nfo.preferredFlags = ToVKTextureMemoryPropertyFlags(
desc.storage_mode, supports_memoryless_textures);
alloc_nfo.flags = ToVmaAllocationCreateFlags(desc.storage_mode, true);

auto create_info_native =
Expand Down Expand Up @@ -336,11 +360,12 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
if (!device_holder) {
return nullptr;
}
auto source =
std::make_shared<AllocatedTextureSourceVK>(desc, //
allocator_, //
device_holder->GetDevice() //
);
auto source = std::make_shared<AllocatedTextureSourceVK>(
desc, //
allocator_, //
device_holder->GetDevice(), //
supports_memoryless_textures_ //
);
if (!source->IsValid()) {
return nullptr;
}
Expand All @@ -365,7 +390,8 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(

VmaAllocationCreateInfo allocation_info = {};
allocation_info.usage = ToVMAMemoryUsage();
allocation_info.preferredFlags = ToVKMemoryPropertyFlags(desc.storage_mode);
allocation_info.preferredFlags =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably use required instead of preferred flags now since we are sure the device supports the type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto for the texture allocation too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah can do that. We will also need to cap check for host visible textures as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to get this working with some quick effort. lets track switching to required flags once we've chased down all the loose ends.

ToVKBufferMemoryPropertyFlags(desc.storage_mode);
allocation_info.flags = ToVmaAllocationCreateFlags(desc.storage_mode, false);

VkBuffer buffer = {};
Expand Down
4 changes: 3 additions & 1 deletion impeller/renderer/backend/vulkan/allocator_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ class AllocatorVK final : public Allocator {
std::weak_ptr<DeviceHolder> device_holder_;
ISize max_texture_size_;
bool is_valid_ = false;
bool supports_memoryless_textures_ = false;

AllocatorVK(std::weak_ptr<Context> context,
uint32_t vulkan_api_version,
const vk::PhysicalDevice& physical_device,
const std::shared_ptr<DeviceHolder>& device_holder,
const vk::Instance& instance,
PFN_vkGetInstanceProcAddr get_instance_proc_address,
PFN_vkGetDeviceProcAddr get_device_proc_address);
PFN_vkGetDeviceProcAddr get_device_proc_address,
const CapabilitiesVK& capabilities);

// |Allocator|
bool IsValid() const;
Expand Down
20 changes: 20 additions & 0 deletions impeller/renderer/backend/vulkan/capabilities_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,21 @@ bool CapabilitiesVK::SetPhysicalDevice(const vk::PhysicalDevice& device) {
.supportedOperations &
vk::SubgroupFeatureFlagBits::eArithmetic);

{
// Query texture support.
// TODO(jonahwilliams):
// https://github.com/flutter/flutter/issues/129784
vk::PhysicalDeviceMemoryProperties memory_properties;
device.getMemoryProperties(&memory_properties);

for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
if (memory_properties.memoryTypes[i].propertyFlags &
vk::MemoryPropertyFlagBits::eLazilyAllocated) {
supports_memoryless_textures_ = true;
}
}
}

// Determine the optional device extensions this physical device supports.
{
optional_device_extensions_.clear();
Expand Down Expand Up @@ -422,6 +437,11 @@ bool CapabilitiesVK::SupportsDecalTileMode() const {
return true;
}

// |Capabilities|
bool CapabilitiesVK::SupportsMemorylessTextures() const {
return supports_memoryless_textures_;
}

// |Capabilities|
PixelFormat CapabilitiesVK::GetDefaultColorFormat() const {
return color_format_;
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/vulkan/capabilities_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class CapabilitiesVK final : public Capabilities,
// |Capabilities|
bool SupportsDecalTileMode() const override;

// |Capabilities|
bool SupportsMemorylessTextures() const override;

// |Capabilities|
PixelFormat GetDefaultColorFormat() const override;

Expand All @@ -104,6 +107,7 @@ class CapabilitiesVK final : public Capabilities,
PixelFormat depth_stencil_format_ = PixelFormat::kUnknown;
vk::PhysicalDeviceProperties device_properties_;
bool supports_compute_subgroups_ = false;
bool supports_memoryless_textures_ = false;
bool is_valid_ = false;

bool HasExtension(const std::string& ext) const;
Expand Down
3 changes: 2 additions & 1 deletion impeller/renderer/backend/vulkan/context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ void ContextVK::Setup(Settings settings) {
device_holder, //
device_holder->instance.get(), //
dispatcher.vkGetInstanceProcAddr, //
dispatcher.vkGetDeviceProcAddr //
dispatcher.vkGetDeviceProcAddr, //
*caps //
));

if (!allocator->IsValid()) {
Expand Down
14 changes: 14 additions & 0 deletions impeller/renderer/capabilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class StandardCapabilities final : public Capabilities {
return default_stencil_format_;
}

bool SupportsMemorylessTextures() const override {
return supports_memoryless_textures_;
}

private:
StandardCapabilities(bool has_threading_restrictions,
bool supports_offscreen_msaa,
Expand All @@ -88,6 +92,7 @@ class StandardCapabilities final : public Capabilities {
bool supports_read_from_onscreen_texture,
bool supports_read_from_resolve,
bool supports_decal_tile_mode,
bool supports_memoryless_textures,
PixelFormat default_color_format,
PixelFormat default_stencil_format)
: has_threading_restrictions_(has_threading_restrictions),
Expand All @@ -102,6 +107,7 @@ class StandardCapabilities final : public Capabilities {
supports_read_from_onscreen_texture),
supports_read_from_resolve_(supports_read_from_resolve),
supports_decal_tile_mode_(supports_decal_tile_mode),
supports_memoryless_textures_(supports_memoryless_textures),
default_color_format_(default_color_format),
default_stencil_format_(default_stencil_format) {}

Expand All @@ -118,6 +124,7 @@ class StandardCapabilities final : public Capabilities {
bool supports_read_from_onscreen_texture_ = false;
bool supports_read_from_resolve_ = false;
bool supports_decal_tile_mode_ = false;
bool supports_memoryless_textures_ = false;
PixelFormat default_color_format_ = PixelFormat::kUnknown;
PixelFormat default_stencil_format_ = PixelFormat::kUnknown;

Expand Down Expand Up @@ -202,6 +209,12 @@ CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsDecalTileMode(bool value) {
return *this;
}

CapabilitiesBuilder& CapabilitiesBuilder::SetSupportsMemorylessTextures(
bool value) {
supports_memoryless_textures_ = value;
return *this;
}

std::unique_ptr<Capabilities> CapabilitiesBuilder::Build() {
return std::unique_ptr<StandardCapabilities>(new StandardCapabilities( //
has_threading_restrictions_, //
Expand All @@ -215,6 +228,7 @@ std::unique_ptr<Capabilities> CapabilitiesBuilder::Build() {
supports_read_from_onscreen_texture_, //
supports_read_from_resolve_, //
supports_decal_tile_mode_, //
supports_memoryless_textures_, //
default_color_format_.value_or(PixelFormat::kUnknown), //
default_stencil_format_.value_or(PixelFormat::kUnknown) //
));
Expand Down
5 changes: 5 additions & 0 deletions impeller/renderer/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class Capabilities {

virtual bool SupportsDecalTileMode() const = 0;

virtual bool SupportsMemorylessTextures() const = 0;

virtual PixelFormat GetDefaultColorFormat() const = 0;

virtual PixelFormat GetDefaultStencilFormat() const = 0;
Expand Down Expand Up @@ -79,6 +81,8 @@ class CapabilitiesBuilder {

CapabilitiesBuilder& SetSupportsDecalTileMode(bool value);

CapabilitiesBuilder& SetSupportsMemorylessTextures(bool value);

std::unique_ptr<Capabilities> Build();

private:
Expand All @@ -93,6 +97,7 @@ class CapabilitiesBuilder {
bool supports_read_from_onscreen_texture_ = false;
bool supports_read_from_resolve_ = false;
bool supports_decal_tile_mode_ = false;
bool supports_memoryless_textures_ = false;
std::optional<PixelFormat> default_color_format_ = std::nullopt;
std::optional<PixelFormat> default_stencil_format_ = std::nullopt;

Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/capabilities_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ CAPABILITY_TEST(SupportsComputeSubgroups, false);
CAPABILITY_TEST(SupportsReadFromOnscreenTexture, false);
CAPABILITY_TEST(SupportsReadFromResolve, false);
CAPABILITY_TEST(SupportsDecalTileMode, false);
CAPABILITY_TEST(SupportsMemorylessTextures, false);

} // namespace testing
} // namespace impeller