Flutter Impeller
impeller::ContextVK Class Referencefinal

#include <context_vk.h>

Inheritance diagram for impeller::ContextVK:
impeller::Context impeller::BackendCast< ContextVK, Context >

Classes

struct  Settings
 

Public Member Functions

uint64_t GetHash () const
 
 ~ContextVK () override
 
BackendType GetBackendType () const override
 Get the graphics backend of an Impeller context. More...
 
std::string DescribeGpuModel () const override
 
bool IsValid () const override
 Determines if a context is valid. If the caller ever receives an invalid context, they must discard it and construct a new context. There is no recovery mechanism to repair a bad context. More...
 
std::shared_ptr< AllocatorGetResourceAllocator () const override
 Returns the allocator used to create textures and buffers on the device. More...
 
std::shared_ptr< ShaderLibraryGetShaderLibrary () const override
 Returns the library of shaders used to specify the programmable stages of a pipeline. More...
 
std::shared_ptr< SamplerLibraryGetSamplerLibrary () const override
 Returns the library of combined image samplers used in shaders. More...
 
std::shared_ptr< PipelineLibraryGetPipelineLibrary () const override
 Returns the library of pipelines used by render or compute commands. More...
 
std::shared_ptr< CommandBufferCreateCommandBuffer () const override
 Create a new command buffer. Command buffers can be used to encode graphics, blit, or compute commands to be submitted to the device. More...
 
const std::shared_ptr< const Capabilities > & GetCapabilities () const override
 Get the capabilities of Impeller context. All optionally supported feature of the platform, client-rendering API, and device can be queried using the Capabilities. More...
 
const std::shared_ptr< YUVConversionLibraryVK > & GetYUVConversionLibrary () const
 
void Shutdown () override
 Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent message loops. More...
 
void SetOffscreenFormat (PixelFormat pixel_format)
 
template<typename T >
bool SetDebugName (T handle, std::string_view label) const
 
std::shared_ptr< DeviceHolderVKGetDeviceHolder () const
 
vk::Instance GetInstance () const
 
const vk::Device & GetDevice () const
 
const std::unique_ptr< DriverInfoVK > & GetDriverInfo () const
 
const std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner () const
 
std::shared_ptr< SurfaceContextVKCreateSurfaceContext ()
 
const std::shared_ptr< QueueVK > & GetGraphicsQueue () const
 
vk::PhysicalDevice GetPhysicalDevice () const
 
std::shared_ptr< FenceWaiterVKGetFenceWaiter () const
 
std::shared_ptr< ResourceManagerVKGetResourceManager () const
 
std::shared_ptr< CommandPoolRecyclerVKGetCommandPoolRecycler () const
 
std::shared_ptr< DescriptorPoolRecyclerVKGetDescriptorPoolRecycler () const
 
std::shared_ptr< CommandQueueGetCommandQueue () const override
 Return the graphics queue for submitting command buffers. More...
 
std::shared_ptr< GPUTracerVKGetGPUTracer () const
 
void RecordFrameEndTime () const
 
void InitializeCommonlyUsedShadersIfNeeded () const override
 
- Public Member Functions inherited from impeller::Context
virtual ~Context ()
 Destroys an Impeller context. More...
 
virtual bool UpdateOffscreenLayerPixelFormat (PixelFormat format)
 
virtual void StoreTaskForGPU (const std::function< void()> &task)
 

Static Public Member Functions

static size_t ChooseThreadCountForWorkers (size_t hardware_concurrency)
 
static std::shared_ptr< ContextVKCreate (Settings settings)
 
template<typename T >
static bool SetDebugName (const vk::Device &device, T handle, std::string_view label)
 
- Static Public Member Functions inherited from impeller::BackendCast< ContextVK, Context >
static ContextVKCast (Context &base)
 
static const ContextVKCast (const Context &base)
 
static ContextVKCast (Context *base)
 
static const ContextVKCast (const Context *base)
 

Additional Inherited Members

- Public Types inherited from impeller::Context
enum  BackendType {
  BackendType::kMetal,
  BackendType::kOpenGLES,
  BackendType::kVulkan
}
 
- Public Attributes inherited from impeller::Context
CaptureContext capture
 
- Static Public Attributes inherited from impeller::Context
static constexpr int32_t kMaxTasksAwaitingGPU = 10
 
- Protected Member Functions inherited from impeller::Context
 Context ()
 
- Protected Attributes inherited from impeller::Context
std::vector< std::function< void()> > per_frame_task_
 

Detailed Description

Definition at line 42 of file context_vk.h.

Constructor & Destructor Documentation

◆ ~ContextVK()

impeller::ContextVK::~ContextVK ( )
override

Definition at line 127 of file context_vk.cc.

127  {
128  if (device_holder_ && device_holder_->device) {
129  [[maybe_unused]] auto result = device_holder_->device->waitIdle();
130  }
132 }

References impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools().

Member Function Documentation

◆ ChooseThreadCountForWorkers()

size_t impeller::ContextVK::ChooseThreadCountForWorkers ( size_t  hardware_concurrency)
static

Choose the number of worker threads the context_vk will create.

Visible for testing.

Definition at line 110 of file context_vk.cc.

110  {
111  // Never create more than 4 worker threads. Attempt to use up to
112  // half of the available concurrency.
113  return std::clamp(hardware_concurrency / 2ull, /*lo=*/1ull, /*hi=*/4ull);
114 }

Referenced by impeller::testing::TEST().

◆ Create()

std::shared_ptr< ContextVK > impeller::ContextVK::Create ( Settings  settings)
static

Definition at line 100 of file context_vk.cc.

100  {
101  auto context = std::shared_ptr<ContextVK>(new ContextVK());
102  context->Setup(std::move(settings));
103  if (!context->IsValid()) {
104  return nullptr;
105  }
106  return context;
107 }

Referenced by impeller::PlaygroundImplVK::PlaygroundImplVK().

◆ CreateCommandBuffer()

std::shared_ptr< CommandBuffer > impeller::ContextVK::CreateCommandBuffer ( ) const
overridevirtual

Create a new command buffer. Command buffers can be used to encode graphics, blit, or compute commands to be submitted to the device.

A command buffer can only be used on a single thread. Multi-threaded render, blit, or compute passes must create a new command buffer on each thread.

Returns
A new command buffer.

Implements impeller::Context.

Definition at line 503 of file context_vk.cc.

503  {
504  return std::shared_ptr<CommandBufferVK>(
505  new CommandBufferVK(shared_from_this(), //
506  CreateGraphicsCommandEncoderFactory()) //
507  );
508 }

Referenced by impeller::GPUTracerVK::InitializeQueryPool().

◆ CreateSurfaceContext()

std::shared_ptr< SurfaceContextVK > impeller::ContextVK::CreateSurfaceContext ( )

Definition at line 535 of file context_vk.cc.

535  {
536  return std::make_shared<SurfaceContextVK>(shared_from_this());
537 }

◆ DescribeGpuModel()

std::string impeller::ContextVK::DescribeGpuModel ( ) const
overridevirtual

Implements impeller::Context.

Definition at line 479 of file context_vk.cc.

479  {
480  return device_name_;
481 }

◆ GetBackendType()

Context::BackendType impeller::ContextVK::GetBackendType ( ) const
overridevirtual

Get the graphics backend of an Impeller context.

        This is useful for cases where a renderer needs to track and
        lookup backend-specific resources, like shaders or uniform
        layout information.

        It's not recommended to use this as a substitute for
        per-backend capability checking. Instead, check for specific
        capabilities via `GetCapabilities()`.
Returns
The graphics backend of the Context.

Implements impeller::Context.

Definition at line 134 of file context_vk.cc.

134  {
136 }

References impeller::Context::kVulkan.

◆ GetCapabilities()

const std::shared_ptr< const Capabilities > & impeller::ContextVK::GetCapabilities ( ) const
overridevirtual

Get the capabilities of Impeller context. All optionally supported feature of the platform, client-rendering API, and device can be queried using the Capabilities.

Returns
The capabilities. Can never be nullptr for a valid context.

Implements impeller::Context.

Definition at line 539 of file context_vk.cc.

539  {
540  return device_capabilities_;
541 }

◆ GetCommandPoolRecycler()

std::shared_ptr< CommandPoolRecyclerVK > impeller::ContextVK::GetCommandPoolRecycler ( ) const

Definition at line 559 of file context_vk.cc.

560  {
561  return command_pool_recycler_;
562 }

◆ GetCommandQueue()

std::shared_ptr< CommandQueue > impeller::ContextVK::GetCommandQueue ( ) const
overridevirtual

Return the graphics queue for submitting command buffers.

Implements impeller::Context.

Definition at line 578 of file context_vk.cc.

578  {
579  return command_queue_vk_;
580 }

Referenced by impeller::GPUTracerVK::InitializeQueryPool().

◆ GetConcurrentWorkerTaskRunner()

const std::shared_ptr< fml::ConcurrentTaskRunner > impeller::ContextVK::GetConcurrentWorkerTaskRunner ( ) const

Definition at line 519 of file context_vk.cc.

519  {
520  return raster_message_loop_->GetTaskRunner();
521 }

◆ GetDescriptorPoolRecycler()

std::shared_ptr< DescriptorPoolRecyclerVK > impeller::ContextVK::GetDescriptorPoolRecycler ( ) const

Definition at line 573 of file context_vk.cc.

574  {
575  return descriptor_pool_recycler_;
576 }

◆ GetDevice()

const vk::Device & impeller::ContextVK::GetDevice ( ) const

Definition at line 514 of file context_vk.cc.

514  {
515  return device_holder_->device.get();
516 }

Referenced by impeller::DescriptorPoolVK::AllocateDescriptorSets(), InitializeCommonlyUsedShadersIfNeeded(), impeller::GPUTracerVK::InitializeQueryPool(), and SetDebugName().

◆ GetDeviceHolder()

std::shared_ptr<DeviceHolderVK> impeller::ContextVK::GetDeviceHolder ( ) const
inline

Definition at line 134 of file context_vk.h.

134  {
135  return device_holder_;
136  }

◆ GetDriverInfo()

const std::unique_ptr< DriverInfoVK > & impeller::ContextVK::GetDriverInfo ( ) const

Definition at line 626 of file context_vk.cc.

626  {
627  return driver_info_;
628 }

Referenced by impeller::testing::TEST_P().

◆ GetFenceWaiter()

std::shared_ptr< FenceWaiterVK > impeller::ContextVK::GetFenceWaiter ( ) const

Definition at line 551 of file context_vk.cc.

551  {
552  return fence_waiter_;
553 }

◆ GetGPUTracer()

std::shared_ptr< GPUTracerVK > impeller::ContextVK::GetGPUTracer ( ) const

Definition at line 569 of file context_vk.cc.

569  {
570  return gpu_tracer_;
571 }

◆ GetGraphicsQueue()

const std::shared_ptr< QueueVK > & impeller::ContextVK::GetGraphicsQueue ( ) const

Definition at line 543 of file context_vk.cc.

543  {
544  return queues_.graphics_queue;
545 }

References impeller::QueuesVK::graphics_queue.

◆ GetHash()

uint64_t impeller::ContextVK::GetHash ( ) const
inline

Definition at line 65 of file context_vk.h.

65 { return hash_; }

Referenced by impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools().

◆ GetInstance()

vk::Instance impeller::ContextVK::GetInstance ( ) const

Definition at line 510 of file context_vk.cc.

510  {
511  return *device_holder_->instance;
512 }

◆ GetPhysicalDevice()

vk::PhysicalDevice impeller::ContextVK::GetPhysicalDevice ( ) const

Definition at line 547 of file context_vk.cc.

547  {
548  return device_holder_->physical_device;
549 }

◆ GetPipelineLibrary()

std::shared_ptr< PipelineLibrary > impeller::ContextVK::GetPipelineLibrary ( ) const
overridevirtual

Returns the library of pipelines used by render or compute commands.

Returns
The pipeline library. Can never be nullptr for a valid context.

Implements impeller::Context.

Definition at line 499 of file context_vk.cc.

499  {
500  return pipeline_library_;
501 }

◆ GetResourceAllocator()

std::shared_ptr< Allocator > impeller::ContextVK::GetResourceAllocator ( ) const
overridevirtual

Returns the allocator used to create textures and buffers on the device.

Returns
The resource allocator. Can never be nullptr for a valid context.

Implements impeller::Context.

Definition at line 487 of file context_vk.cc.

487  {
488  return allocator_;
489 }

Referenced by InitializeCommonlyUsedShadersIfNeeded().

◆ GetResourceManager()

std::shared_ptr< ResourceManagerVK > impeller::ContextVK::GetResourceManager ( ) const

Definition at line 555 of file context_vk.cc.

555  {
556  return resource_manager_;
557 }

◆ GetSamplerLibrary()

std::shared_ptr< SamplerLibrary > impeller::ContextVK::GetSamplerLibrary ( ) const
overridevirtual

Returns the library of combined image samplers used in shaders.

Returns
The sampler library. Can never be nullptr for a valid context.

Implements impeller::Context.

Definition at line 495 of file context_vk.cc.

495  {
496  return sampler_library_;
497 }

◆ GetShaderLibrary()

std::shared_ptr< ShaderLibrary > impeller::ContextVK::GetShaderLibrary ( ) const
overridevirtual

Returns the library of shaders used to specify the programmable stages of a pipeline.

Returns
The shader library. Can never be nullptr for a valid context.

Implements impeller::Context.

Definition at line 491 of file context_vk.cc.

491  {
492  return shader_library_;
493 }

◆ GetYUVConversionLibrary()

const std::shared_ptr< YUVConversionLibraryVK > & impeller::ContextVK::GetYUVConversionLibrary ( ) const

Definition at line 622 of file context_vk.cc.

622  {
623  return yuv_conversion_library_;
624 }

Referenced by impeller::CreateYUVConversion().

◆ InitializeCommonlyUsedShadersIfNeeded()

void impeller::ContextVK::InitializeCommonlyUsedShadersIfNeeded ( ) const
overridevirtual

Run backend specific additional setup and create common shader variants.

This bootstrap is intended to improve the performance of several first frame benchmarks that are tracked in the flutter device lab. The workload includes initializing commonly used but not default shader variants, as well as forcing driver initialization.

Reimplemented from impeller::Context.

Definition at line 585 of file context_vk.cc.

585  {
586  RenderTargetAllocator rt_allocator(GetResourceAllocator());
587  RenderTarget render_target =
588  rt_allocator.CreateOffscreenMSAA(*this, {1, 1}, 1);
589 
590  RenderPassBuilderVK builder;
591  for (const auto& [bind_point, color] : render_target.GetColorAttachments()) {
592  builder.SetColorAttachment(
593  bind_point, //
594  color.texture->GetTextureDescriptor().format, //
595  color.texture->GetTextureDescriptor().sample_count, //
596  color.load_action, //
597  color.store_action //
598  );
599  }
600 
601  if (auto depth = render_target.GetDepthAttachment(); depth.has_value()) {
602  builder.SetDepthStencilAttachment(
603  depth->texture->GetTextureDescriptor().format, //
604  depth->texture->GetTextureDescriptor().sample_count, //
605  depth->load_action, //
606  depth->store_action //
607  );
608  } else if (auto stencil = render_target.GetStencilAttachment();
609  stencil.has_value()) {
610  builder.SetStencilAttachment(
611  stencil->texture->GetTextureDescriptor().format, //
612  stencil->texture->GetTextureDescriptor().sample_count, //
613  stencil->load_action, //
614  stencil->store_action //
615  );
616  }
617 
618  auto pass = builder.Build(GetDevice());
619 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderTargetAllocator::CreateOffscreenMSAA(), impeller::RenderTarget::GetColorAttachments(), impeller::RenderTarget::GetDepthAttachment(), GetDevice(), GetResourceAllocator(), impeller::RenderTarget::GetStencilAttachment(), impeller::RenderPassBuilderVK::SetColorAttachment(), impeller::RenderPassBuilderVK::SetDepthStencilAttachment(), and impeller::RenderPassBuilderVK::SetStencilAttachment().

◆ IsValid()

bool impeller::ContextVK::IsValid ( ) const
overridevirtual

Determines if a context is valid. If the caller ever receives an invalid context, they must discard it and construct a new context. There is no recovery mechanism to repair a bad context.

It is convention in Impeller to never return an invalid context from a call that returns an pointer to a context. The call implementation performs validity checks itself and return a null context instead of a pointer to an invalid context.

How a context goes invalid is backend specific. It could happen due to device loss, or any other unrecoverable error.

Returns
If the context is valid.

Implements impeller::Context.

Definition at line 483 of file context_vk.cc.

483  {
484  return is_valid_;
485 }

◆ RecordFrameEndTime()

void impeller::ContextVK::RecordFrameEndTime ( ) const

◆ SetDebugName() [1/2]

template<typename T >
static bool impeller::ContextVK::SetDebugName ( const vk::Device &  device,
handle,
std::string_view  label 
)
inlinestatic

Definition at line 111 of file context_vk.h.

113  {
114  if (!HasValidationLayers()) {
115  // No-op if validation layers are not enabled.
116  return true;
117  }
118 
119  auto c_handle = static_cast<typename T::CType>(handle);
120 
121  vk::DebugUtilsObjectNameInfoEXT info;
122  info.objectType = T::objectType;
123  info.pObjectName = label.data();
124  info.objectHandle = reinterpret_cast<decltype(info.objectHandle)>(c_handle);
125 
126  if (device.setDebugUtilsObjectNameEXT(info) != vk::Result::eSuccess) {
127  VALIDATION_LOG << "Unable to set debug name: " << label;
128  return false;
129  }
130 
131  return true;
132  }

References impeller::HasValidationLayers(), and VALIDATION_LOG.

◆ SetDebugName() [2/2]

template<typename T >
bool impeller::ContextVK::SetDebugName ( handle,
std::string_view  label 
) const
inline

Definition at line 106 of file context_vk.h.

106  {
107  return SetDebugName(GetDevice(), handle, label);
108  }

References GetDevice().

Referenced by impeller::PipelineVK::Create(), impeller::CreateCompatRenderPassForPipeline(), impeller::CreateSampler(), and impeller::QueuesVK::QueuesVK().

◆ SetOffscreenFormat()

void impeller::ContextVK::SetOffscreenFormat ( PixelFormat  pixel_format)

Definition at line 474 of file context_vk.cc.

474  {
475  CapabilitiesVK::Cast(*device_capabilities_).SetOffscreenFormat(pixel_format);
476 }

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), and impeller::CapabilitiesVK::SetOffscreenFormat().

◆ Shutdown()

void impeller::ContextVK::Shutdown ( )
overridevirtual

Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent message loops.

Implements impeller::Context.

Definition at line 523 of file context_vk.cc.

523  {
524  // There are multiple objects, for example |CommandPoolVK|, that in their
525  // destructors make a strong reference to |ContextVK|. Resetting these shared
526  // pointers ensures that cleanup happens in a correct order.
527  //
528  // tl;dr: Without it, we get thread::join failures on shutdown.
529  fence_waiter_.reset();
530  resource_manager_.reset();
531 
532  raster_message_loop_->Terminate();
533 }

The documentation for this class was generated from the following files:
impeller::CapabilitiesVK::SetOffscreenFormat
void SetOffscreenFormat(PixelFormat pixel_format) const
Definition: capabilities_vk.cc:410
impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools
static void DestroyThreadLocalPools(const ContextVK *context)
Clean up resources held by all per-thread command pools associated with the given context.
Definition: command_pool_vk.cc:285
impeller::ContextVK::GetResourceAllocator
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
Definition: context_vk.cc:487
impeller::QueuesVK::graphics_queue
std::shared_ptr< QueueVK > graphics_queue
Definition: queue_vk.h:62
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:106
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::Context::BackendType::kVulkan
@ kVulkan
impeller::ContextVK::GetDevice
const vk::Device & GetDevice() const
Definition: context_vk.cc:514
impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast
static CapabilitiesVK & Cast(Capabilities &base)
Definition: backend_cast.h:13
impeller::HasValidationLayers
bool HasValidationLayers()
Definition: context_vk.cc:48