Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Next Next commit
[Impeller] less hacky but still hacky cache.
  • Loading branch information
jonahwilliams committed Aug 9, 2023
commit 7fcb5e5d7f3587c642d0432bebbd69bb277a5363
25 changes: 23 additions & 2 deletions impeller/core/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ std::shared_ptr<Texture> Allocator::CreateTexture(
<< " exceeds maximum supported size of " << max_size;
return nullptr;
}
if (desc.ignore_cache) {
return OnCreateTexture(desc);
}
if (desc.storage_mode != StorageMode::kHostVisible) {
for (auto& td : data_to_recycle_) {
const auto other_desc = td.texture->GetTextureDescriptor();
if (!td.used_this_frame &&
desc.size.width == other_desc.size.width &&
desc.size.height == other_desc.size.height &&
desc.storage_mode == other_desc.storage_mode &&
desc.format == other_desc.format &&
desc.usage == other_desc.usage &&
desc.sample_count == other_desc.sample_count &&
desc.type == other_desc.type) {
td.used_this_frame = true;
return td.texture;
}
}
auto result = OnCreateTexture(desc);
data_to_recycle_.push_back({.used_this_frame = true,
.texture = result});
return result;
}

return OnCreateTexture(desc);
}
Expand All @@ -61,6 +84,4 @@ uint16_t Allocator::MinimumBytesPerRow(PixelFormat format) const {
return BytesPerPixelForPixelFormat(format);
}

void Allocator::DidAcquireSurfaceFrame() {}

} // namespace impeller
27 changes: 26 additions & 1 deletion impeller/core/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "flutter/fml/mapping.h"
#include "impeller/core/device_buffer_descriptor.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/geometry/size.h"

namespace impeller {

Expand Down Expand Up @@ -47,7 +48,24 @@ class Allocator {

/// @brief Increment an internal frame used to cycle through a ring buffer of
/// allocation pools.
virtual void DidAcquireSurfaceFrame();
virtual void DidAcquireSurfaceFrame() {
for (auto& td : data_to_recycle_) {
td.used_this_frame = false;
}
}

virtual void DidFinishSurfaceFrame() {
std::vector<TextureData> retain;

for (auto td : data_to_recycle_) {
if (td.used_this_frame) {
retain.push_back(td);
}
}
data_to_recycle_.clear();
data_to_recycle_.insert(data_to_recycle_.end(), retain.begin(),
retain.end());
}

protected:
Allocator();
Expand All @@ -59,6 +77,13 @@ class Allocator {
const TextureDescriptor& desc) = 0;

private:
struct TextureData {
bool used_this_frame;
std::shared_ptr<Texture> texture;
};

std::vector<TextureData> data_to_recycle_;

FML_DISALLOW_COPY_AND_ASSIGN(Allocator);
};

Expand Down
1 change: 1 addition & 0 deletions impeller/core/texture_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct TextureDescriptor {
static_cast<TextureUsageMask>(TextureUsage::kShaderRead);
SampleCount sample_count = SampleCount::kCount1;
CompressionType compression_type = CompressionType::kLossless;
bool ignore_cache = false;

constexpr size_t GetByteSizeOfBaseMipLevel() const {
if (!IsValid()) {
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/vulkan/allocator_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ std::shared_ptr<Texture> AllocatorVK::OnCreateTexture(
void AllocatorVK::DidAcquireSurfaceFrame() {
frame_count_++;
raster_thread_id_ = std::this_thread::get_id();
Allocator::DidAcquireSurfaceFrame();
}

// |Allocator|
Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/vulkan/surface_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
msaa_tex_desc.format = swapchain_image->GetPixelFormat();
msaa_tex_desc.size = swapchain_image->GetSize();
msaa_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
msaa_tex_desc.ignore_cache = true;

std::shared_ptr<Texture> msaa_tex;
if (!swapchain_image->HasMSAATexture()) {
Expand All @@ -47,6 +48,7 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
resolve_tex_desc.sample_count = SampleCount::kCount1;
resolve_tex_desc.storage_mode = StorageMode::kDevicePrivate;
resolve_tex_desc.ignore_cache = true;

std::shared_ptr<Texture> resolve_tex =
std::make_shared<TextureVK>(context, //
Expand Down
106 changes: 53 additions & 53 deletions impeller/renderer/backend/vulkan/swapchain_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -390,66 +390,66 @@ bool SwapchainImplVK::Present(const std::shared_ptr<SwapchainImageVK>& image,
if (!context_strong) {
return false;
}

const auto& context = ContextVK::Cast(*context_strong);
const auto& sync = synchronizers_[current_frame_];

//----------------------------------------------------------------------------
/// Transition the image to color-attachment-optimal.
///
sync->final_cmd_buffer = context.CreateCommandBuffer();
if (!sync->final_cmd_buffer) {
return false;
}

auto vk_final_cmd_buffer = CommandBufferVK::Cast(*sync->final_cmd_buffer)
.GetEncoder()
->GetCommandBuffer();
{
BarrierVK barrier;
barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
barrier.cmd_buffer = vk_final_cmd_buffer;
barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
barrier.dst_access = {};
barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;

if (!image->SetLayout(barrier)) {
return false;
}

if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) {
return false;
}
}

//----------------------------------------------------------------------------
/// Signal that the presentation semaphore is ready.
///
{
vk::SubmitInfo submit_info;
vk::PipelineStageFlags wait_stage =
vk::PipelineStageFlagBits::eColorAttachmentOutput;
submit_info.setWaitDstStageMask(wait_stage);
submit_info.setWaitSemaphores(*sync->render_ready);
submit_info.setSignalSemaphores(*sync->present_ready);
submit_info.setCommandBuffers(vk_final_cmd_buffer);
auto result =
context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire);
if (result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not wait on render semaphore: "
<< vk::to_string(result);
return false;
}
}
context_strong->GetResourceAllocator()->DidFinishSurfaceFrame();

context.GetConcurrentWorkerTaskRunner()->PostTask(
[&, index, image, current_frame = current_frame_] {
[&, index, image] {
auto context_strong = context_.lock();
if (!context_strong) {
return;
}
const auto& context = ContextVK::Cast(*context_strong);
const auto& sync = synchronizers_[current_frame];

//----------------------------------------------------------------------------
/// Transition the image to color-attachment-optimal.
///
sync->final_cmd_buffer = context.CreateCommandBuffer();
if (!sync->final_cmd_buffer) {
return;
}

auto vk_final_cmd_buffer =
CommandBufferVK::Cast(*sync->final_cmd_buffer)
.GetEncoder()
->GetCommandBuffer();
{
BarrierVK barrier;
barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
barrier.cmd_buffer = vk_final_cmd_buffer;
barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
barrier.dst_access = {};
barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;

if (!image->SetLayout(barrier)) {
return;
}

if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) {
return;
}
}

//----------------------------------------------------------------------------
/// Signal that the presentation semaphore is ready.
///
{
vk::SubmitInfo submit_info;
vk::PipelineStageFlags wait_stage =
vk::PipelineStageFlagBits::eColorAttachmentOutput;
submit_info.setWaitDstStageMask(wait_stage);
submit_info.setWaitSemaphores(*sync->render_ready);
submit_info.setSignalSemaphores(*sync->present_ready);
submit_info.setCommandBuffers(vk_final_cmd_buffer);
auto result =
context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire);
if (result != vk::Result::eSuccess) {
VALIDATION_LOG << "Could not wait on render semaphore: "
<< vk::to_string(result);
return;
}
}

//----------------------------------------------------------------------------
/// Present the image.
Expand Down