Skip to content

Commit 80942d5

Browse files
author
Jonah Williams
authored
[Impeller] fixes for AHB swapchains. (#161562)
Fixes for a variety of speculative fixes for AHB swapchain issues. Details TBD while some tests run... 1. Even If the SurfaceControl API is supported, there is no guarantee that we can import the AHB as there may be a mismatch in the required memory properties and what is available. Add a validity check to the texture pool and bail from the swapchain if any are invalid. 2. Rather than submitting a dummy cmd buffer that does a layout transition, use the final command buffer signal semaphore. 3. Import the render ready semaphore and use it to block the onscreen command buffer.
1 parent 3da003c commit 80942d5

3 files changed

Lines changed: 43 additions & 52 deletions

File tree

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,11 @@
66

77
#include "flutter/fml/trace_event.h"
88
#include "impeller/base/validation.h"
9-
#include "impeller/renderer/backend/vulkan/barrier_vk.h"
109
#include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
11-
#include "impeller/renderer/backend/vulkan/fence_waiter_vk.h"
12-
#include "impeller/renderer/backend/vulkan/gpu_tracer_vk.h"
1310
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_formats.h"
1411
#include "impeller/renderer/backend/vulkan/swapchain/surface_vk.h"
1512
#include "impeller/toolkit/android/surface_transaction.h"
1613
#include "impeller/toolkit/android/surface_transaction_stats.h"
17-
#include "vulkan/vulkan_to_string.hpp"
1814

1915
namespace impeller {
2016

@@ -96,6 +92,7 @@ std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
9692
}
9793
}
9894

95+
frame_index_ = (frame_index_ + 1) % kMaxPendingPresents;
9996
AutoSemaSignaler auto_sema_signaler =
10097
std::make_shared<fml::ScopedCleanupClosure>(
10198
[sema = pending_presents_]() { sema->Signal(); });
@@ -111,8 +108,8 @@ std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
111108
return nullptr;
112109
}
113110

114-
// Ask the GPU to wait for the render ready semaphore to be signaled before
115-
// performing rendering operations.
111+
// Import the render ready semaphore that will block onscreen rendering until
112+
// it is ready.
116113
if (!SubmitWaitForRenderReady(pool_entry.render_ready_fence,
117114
pool_entry.texture)) {
118115
VALIDATION_LOG << "Could wait on render ready fence.";
@@ -194,11 +191,7 @@ bool AHBSwapchainImplVK::Present(
194191

195192
void AHBSwapchainImplVK::AddFinalCommandBuffer(
196193
std::shared_ptr<CommandBuffer> cmd_buffer) {
197-
auto context = transients_->GetContext().lock();
198-
if (!context) {
199-
return;
200-
}
201-
context->GetCommandQueue()->Submit({std::move(cmd_buffer)});
194+
frame_data_[frame_index_].command_buffer = std::move(cmd_buffer);
202195
}
203196

204197
std::shared_ptr<ExternalFenceVK>
@@ -213,34 +206,26 @@ AHBSwapchainImplVK::SubmitSignalForPresentReady(
213206
return nullptr;
214207
}
215208

216-
auto command_buffer = context->CreateCommandBuffer();
209+
auto command_buffer = frame_data_[frame_index_].command_buffer;
217210
if (!command_buffer) {
218211
return nullptr;
219212
}
220-
command_buffer->SetLabel("AHBSubmitSignalForPresentReadyCB");
221213
CommandBufferVK& command_buffer_vk = CommandBufferVK::Cast(*command_buffer);
222-
223214
const auto command_encoder_vk = command_buffer_vk.GetCommandBuffer();
224-
225-
BarrierVK barrier;
226-
barrier.cmd_buffer = command_encoder_vk;
227-
barrier.new_layout = vk::ImageLayout::eGeneral;
228-
barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
229-
barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
230-
barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
231-
barrier.dst_access = {};
232-
233-
if (!texture->SetLayout(barrier).ok()) {
234-
return nullptr;
235-
}
236-
237215
command_buffer_vk.Track(fence->GetSharedHandle());
238216

239217
if (!command_buffer_vk.EndCommandBuffer()) {
240218
return nullptr;
241219
}
242220

243221
vk::SubmitInfo submit_info;
222+
vk::PipelineStageFlags wait_stage =
223+
vk::PipelineStageFlagBits::eColorAttachmentOutput;
224+
if (frame_data_[frame_index_].semaphore) {
225+
submit_info.setPWaitSemaphores(&frame_data_[frame_index_].semaphore.get());
226+
submit_info.setWaitSemaphoreCount(1);
227+
submit_info.setWaitDstStageMask(wait_stage);
228+
}
244229
submit_info.setCommandBuffers(command_encoder_vk);
245230

246231
auto result = ContextVK::Cast(*context).GetGraphicsQueue()->Submit(
@@ -251,7 +236,7 @@ AHBSwapchainImplVK::SubmitSignalForPresentReady(
251236
return fence;
252237
}
253238

254-
vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
239+
vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore(
255240
const std::shared_ptr<fml::UniqueFD>& fd) const {
256241
if (!fd->is_valid()) {
257242
return {};
@@ -265,22 +250,22 @@ vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
265250
const auto& context_vk = ContextVK::Cast(*context);
266251
const auto& device = context_vk.GetDevice();
267252

268-
auto signal_wait = device.createFenceUnique({});
253+
auto signal_wait = device.createSemaphoreUnique({});
269254

270255
if (signal_wait.result != vk::Result::eSuccess) {
271256
return {};
272257
}
273258

274-
context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadyFence");
259+
context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadySemaphore");
275260

276-
vk::ImportFenceFdInfoKHR import_info;
277-
import_info.fence = *signal_wait.value;
261+
vk::ImportSemaphoreFdInfoKHR import_info;
262+
import_info.semaphore = *signal_wait.value;
278263
import_info.fd = fd->get();
279-
import_info.handleType = vk::ExternalFenceHandleTypeFlagBits::eSyncFd;
264+
import_info.handleType = vk::ExternalSemaphoreHandleTypeFlagBits::eSyncFd;
280265
// From the spec: Sync FDs can only be imported temporarily.
281-
import_info.flags = vk::FenceImportFlagBitsKHR::eTemporary;
266+
import_info.flags = vk::SemaphoreImportFlagBitsKHR::eTemporary;
282267

283-
const auto import_result = device.importFenceFdKHR(import_info);
268+
const auto import_result = device.importSemaphoreFdKHR(import_info);
284269

285270
if (import_result != vk::Result::eSuccess) {
286271
VALIDATION_LOG << "Could not import semaphore FD: "
@@ -299,10 +284,11 @@ vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
299284

300285
bool AHBSwapchainImplVK::SubmitWaitForRenderReady(
301286
const std::shared_ptr<fml::UniqueFD>& render_ready_fence,
302-
const std::shared_ptr<AHBTextureSourceVK>& texture) const {
287+
const std::shared_ptr<AHBTextureSourceVK>& texture) {
303288
// If there is no render ready fence, we are already ready to render into
304289
// the texture. There is nothing more to do.
305290
if (!render_ready_fence || !render_ready_fence->is_valid()) {
291+
frame_data_[frame_index_].semaphore = {};
306292
return true;
307293
}
308294

@@ -311,20 +297,13 @@ bool AHBSwapchainImplVK::SubmitWaitForRenderReady(
311297
return false;
312298
}
313299

314-
auto fence = CreateRenderReadyFence(render_ready_fence);
315-
316-
auto result = ContextVK::Cast(*context).GetDevice().waitForFences(
317-
*fence, // fence
318-
true, // wait all
319-
std::numeric_limits<uint64_t>::max() // timeout (ns)
320-
);
321-
322-
if (!(result == vk::Result::eSuccess || result == vk::Result::eTimeout)) {
323-
VALIDATION_LOG << "Encountered error while waiting on swapchain image: "
324-
<< vk::to_string(result);
300+
auto semaphore = CreateRenderReadySemaphore(render_ready_fence);
301+
if (!semaphore) {
325302
return false;
326303
}
327-
304+
// This semaphore will be later used to block the onscreen render pass
305+
// from starting until the system is done reading the onscreen.
306+
frame_data_[frame_index_].semaphore = std::move(semaphore);
328307
return true;
329308
}
330309

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "impeller/renderer/surface.h"
1818
#include "impeller/toolkit/android/hardware_buffer.h"
1919
#include "impeller/toolkit/android/surface_control.h"
20+
#include "vulkan/vulkan_handles.hpp"
2021

2122
namespace impeller {
2223

@@ -104,7 +105,14 @@ class AHBSwapchainImplVK final
104105
std::shared_ptr<AHBTextureSourceVK> currently_displayed_texture_
105106
IPLR_GUARDED_BY(currently_displayed_texture_mutex_);
106107
std::shared_ptr<fml::Semaphore> pending_presents_;
107-
std::shared_ptr<CommandBuffer> pending_cmd_buffer_;
108+
109+
struct FrameData {
110+
std::shared_ptr<CommandBuffer> command_buffer;
111+
vk::UniqueSemaphore semaphore;
112+
};
113+
114+
std::array<FrameData, 3> frame_data_;
115+
size_t frame_index_ = 0;
108116
bool is_valid_ = false;
109117

110118
explicit AHBSwapchainImplVK(
@@ -117,12 +125,12 @@ class AHBSwapchainImplVK final
117125
bool Present(const AutoSemaSignaler& signaler,
118126
const std::shared_ptr<AHBTextureSourceVK>& texture);
119127

120-
vk::UniqueFence CreateRenderReadyFence(
128+
vk::UniqueSemaphore CreateRenderReadySemaphore(
121129
const std::shared_ptr<fml::UniqueFD>& fd) const;
122130

123131
bool SubmitWaitForRenderReady(
124132
const std::shared_ptr<fml::UniqueFD>& render_ready_fence,
125-
const std::shared_ptr<AHBTextureSourceVK>& texture) const;
133+
const std::shared_ptr<AHBTextureSourceVK>& texture);
126134

127135
std::shared_ptr<ExternalFenceVK> SubmitSignalForPresentReady(
128136
const std::shared_ptr<AHBTextureSourceVK>& texture) const;

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_texture_pool_vk.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ AHBTexturePoolVK::AHBTexturePoolVK(std::weak_ptr<Context> context,
1717
return;
1818
}
1919
for (auto i = 0u; i < max_entries_; i++) {
20-
pool_.emplace_back(CreateTexture());
20+
auto texture = CreateTexture();
21+
if (!texture->IsValid()) {
22+
return;
23+
}
24+
pool_.emplace_back(std::move(texture));
2125
}
2226
is_valid_ = true;
2327
}

0 commit comments

Comments
 (0)