Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Friends | List of all members
impeller::RenderPassVK Class Referencefinal

#include <render_pass_vk.h>

Inheritance diagram for impeller::RenderPassVK:
impeller::RenderPass impeller::ResourceBinder

Public Member Functions

 ~RenderPassVK () override
 
- Public Member Functions inherited from impeller::RenderPass
virtual ~RenderPass ()
 
const std::shared_ptr< const Context > & GetContext () const
 
const RenderTargetGetRenderTarget () const
 
ISize GetRenderTargetSize () const
 
const MatrixGetOrthographicTransform () const
 
void SetLabel (std::string label)
 
bool EncodeCommands () const
 Encode the recorded commands to the underlying command buffer.
 
virtual const std::vector< Command > & GetCommands () const
 Accessor for the current Commands.
 
SampleCount GetSampleCount () const
 The sample count of the attached render target.
 
PixelFormat GetRenderTargetPixelFormat () const
 The pixel format of the attached render target.
 
bool HasDepthAttachment () const
 Whether the render target has a depth attachment.
 
bool HasStencilAttachment () const
 Whether the render target has an stencil attachment.
 
- Public Member Functions inherited from impeller::ResourceBinder
virtual ~ResourceBinder ()=default
 

Private Member Functions

void SetPipeline (const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline) override
 The pipeline to use for this command.
 
void SetCommandLabel (std::string_view label) override
 The debugging label to use for the command.
 
void SetStencilReference (uint32_t value) override
 
void SetBaseVertex (uint64_t value) override
 
void SetViewport (Viewport viewport) override
 
void SetScissor (IRect scissor) override
 
void SetInstanceCount (size_t count) override
 
bool SetVertexBuffer (VertexBuffer buffer) override
 Specify the vertex and index buffer to use for this command.
 
fml::Status Draw () override
 Record the currently pending command.
 
void ReserveCommands (size_t command_count) override
 Reserve [command_count] commands in the HAL command buffer.
 
bool BindResource (ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const ShaderMetadata &metadata, BufferView view) override
 
bool BindResource (ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const std::shared_ptr< const ShaderMetadata > &metadata, BufferView view) override
 
bool BindResource (ShaderStage stage, DescriptorType type, const SampledImageSlot &slot, const ShaderMetadata &metadata, std::shared_ptr< const Texture > texture, const std::unique_ptr< const Sampler > &sampler) override
 
bool IsValid () const override
 
void OnSetLabel (std::string label) override
 
bool OnEncodeCommands (const Context &context) const override
 

Friends

class CommandBufferVK
 

Additional Inherited Members

- Protected Member Functions inherited from impeller::RenderPass
bool AddCommand (Command &&command)
 Record a command for subsequent encoding to the underlying command buffer. No work is encoded into the command buffer at this time.
 
 RenderPass (std::shared_ptr< const Context > context, const RenderTarget &target)
 
- Protected Attributes inherited from impeller::RenderPass
const std::shared_ptr< const Contextcontext_
 
const SampleCount sample_count_
 
const PixelFormat pixel_format_
 
const bool has_depth_attachment_
 
const bool has_stencil_attachment_
 
const ISize render_target_size_
 
const RenderTarget render_target_
 
std::vector< Commandcommands_
 
const Matrix orthographic_
 

Detailed Description

Definition at line 22 of file render_pass_vk.h.

Constructor & Destructor Documentation

◆ ~RenderPassVK()

impeller::RenderPassVK::~RenderPassVK ( )
overridedefault

Member Function Documentation

◆ BindResource() [1/3]

bool impeller::RenderPassVK::BindResource ( ShaderStage  stage,
DescriptorType  type,
const SampledImageSlot slot,
const ShaderMetadata metadata,
std::shared_ptr< const Texture texture,
const std::unique_ptr< const Sampler > &  sampler 
)
overrideprivatevirtual

Reimplemented from impeller::RenderPass.

Definition at line 585 of file render_pass_vk.cc.

590 {
591 if (bound_buffer_offset_ >= kMaxBindings) {
592 return false;
593 }
594 if (!texture->IsValid() || !sampler) {
595 return false;
596 }
597 const TextureVK& texture_vk = TextureVK::Cast(*texture);
598 const SamplerVK& sampler_vk = SamplerVK::Cast(*sampler);
599
600 if (!command_buffer_->GetEncoder()->Track(texture)) {
601 return false;
602 }
603
604 if (!immutable_sampler_) {
605 immutable_sampler_ = texture_vk.GetImmutableSamplerVariant(sampler_vk);
606 }
607
608 vk::DescriptorImageInfo image_info;
609 image_info.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
610 image_info.sampler = sampler_vk.GetSampler();
611 image_info.imageView = texture_vk.GetImageView();
612 image_workspace_[bound_image_offset_++] = image_info;
613
614 vk::WriteDescriptorSet write_set;
615 write_set.dstBinding = slot.binding;
616 write_set.descriptorCount = 1u;
617 write_set.descriptorType = vk::DescriptorType::eCombinedImageSampler;
618 write_set.pImageInfo = &image_workspace_[bound_image_offset_ - 1];
619
620 write_workspace_[descriptor_write_offset_++] = write_set;
621 return true;
622}
static TextureVK & Cast(Texture &base)
FlTexture * texture
static constexpr size_t kMaxBindings
Definition pipeline_vk.h:26

◆ BindResource() [2/3]

bool impeller::RenderPassVK::BindResource ( ShaderStage  stage,
DescriptorType  type,
const ShaderUniformSlot slot,
const ShaderMetadata metadata,
BufferView  view 
)
overrideprivatevirtual

Reimplemented from impeller::RenderPass.

Definition at line 533 of file render_pass_vk.cc.

537 {
538 return BindResource(slot.binding, type, view);
539}
bool BindResource(ShaderStage stage, DescriptorType type, const ShaderUniformSlot &slot, const ShaderMetadata &metadata, BufferView view) override

◆ BindResource() [3/3]

bool impeller::RenderPassVK::BindResource ( ShaderStage  stage,
DescriptorType  type,
const ShaderUniformSlot slot,
const std::shared_ptr< const ShaderMetadata > &  metadata,
BufferView  view 
)
overrideprivatevirtual

Reimplemented from impeller::RenderPass.

Definition at line 541 of file render_pass_vk.cc.

546 {
547 return BindResource(slot.binding, type, view);
548}

◆ Draw()

fml::Status impeller::RenderPassVK::Draw ( )
overrideprivatevirtual

Record the currently pending command.

If there are immutable samplers referenced in the render pass, the base pipeline variant is no longer valid and needs to be re-constructed to reference the samplers.

This is an instance of JIT creation of PSOs that can cause jank. It is unavoidable because it isn't possible to know all possible combinations of target YUV conversions. Fortunately, this will only ever happen when rendering to external textures. Like Android Hardware Buffers on Android.

Even when JIT creation is unavoidable, pipelines will cache their variants when able and all pipeline creation will happen via a base pipeline cache anyway. So the jank can be mostly entirely ameliorated and it should only ever happen when the first unknown YUV conversion is encountered.

Jank can be completely eliminated by pre-populating known YUV conversion pipelines.

Reimplemented from impeller::RenderPass.

Definition at line 425 of file render_pass_vk.cc.

425 {
426 if (!pipeline_) {
428 "No valid pipeline is bound to the RenderPass.");
429 }
430
431 //----------------------------------------------------------------------------
432 /// If there are immutable samplers referenced in the render pass, the base
433 /// pipeline variant is no longer valid and needs to be re-constructed to
434 /// reference the samplers.
435 ///
436 /// This is an instance of JIT creation of PSOs that can cause jank. It is
437 /// unavoidable because it isn't possible to know all possible combinations of
438 /// target YUV conversions. Fortunately, this will only ever happen when
439 /// rendering to external textures. Like Android Hardware Buffers on Android.
440 ///
441 /// Even when JIT creation is unavoidable, pipelines will cache their variants
442 /// when able and all pipeline creation will happen via a base pipeline cache
443 /// anyway. So the jank can be mostly entirely ameliorated and it should only
444 /// ever happen when the first unknown YUV conversion is encountered.
445 ///
446 /// Jank can be completely eliminated by pre-populating known YUV conversion
447 /// pipelines.
448 if (immutable_sampler_) {
449 std::shared_ptr<PipelineVK> pipeline_variant =
450 PipelineVK::Cast(*pipeline_)
451 .CreateVariantForImmutableSamplers(immutable_sampler_);
452 if (!pipeline_variant) {
453 return fml::Status(
455 "Could not create pipeline variant with immutable sampler.");
456 }
457 pipeline_ = pipeline_variant.get();
458 }
459
460 const auto& context_vk = ContextVK::Cast(*context_);
461 const auto& pipeline_vk = PipelineVK::Cast(*pipeline_);
462
463 auto descriptor_result =
464 command_buffer_->GetEncoder()->AllocateDescriptorSets(
465 pipeline_vk.GetDescriptorSetLayout(), context_vk);
466 if (!descriptor_result.ok()) {
468 "Could not allocate descriptor sets.");
469 }
470 const auto descriptor_set = descriptor_result.value();
471 const auto pipeline_layout = pipeline_vk.GetPipelineLayout();
472 command_buffer_vk_.bindPipeline(vk::PipelineBindPoint::eGraphics,
473 pipeline_vk.GetPipeline());
474
475 for (auto i = 0u; i < descriptor_write_offset_; i++) {
476 write_workspace_[i].dstSet = descriptor_set;
477 }
478
479 context_vk.GetDevice().updateDescriptorSets(descriptor_write_offset_,
480 write_workspace_.data(), 0u, {});
481
482 command_buffer_vk_.bindDescriptorSets(
483 vk::PipelineBindPoint::eGraphics, // bind point
484 pipeline_layout, // layout
485 0, // first set
486 1, // set count
487 &descriptor_set, // sets
488 0, // offset count
489 nullptr // offsets
490 );
491
492 if (pipeline_uses_input_attachments_) {
494 command_buffer_vk_, TextureVK::Cast(*color_image_vk_).GetImage());
495 }
496
497 if (has_index_buffer_) {
498 command_buffer_vk_.drawIndexed(vertex_count_, // index count
499 instance_count_, // instance count
500 0u, // first index
501 base_vertex_, // vertex offset
502 0u // first instance
503 );
504 } else {
505 command_buffer_vk_.draw(vertex_count_, // vertex count
506 instance_count_, // instance count
507 base_vertex_, // vertex offset
508 0u // first instance
509 );
510 }
511
512#ifdef IMPELLER_DEBUG
513 if (has_label_) {
514 command_buffer_->GetEncoder()->PopDebugGroup();
515 }
516#endif // IMPELLER_DEBUG
517 has_label_ = false;
518 has_index_buffer_ = false;
519 bound_image_offset_ = 0u;
520 bound_buffer_offset_ = 0u;
521 descriptor_write_offset_ = 0u;
522 instance_count_ = 1u;
523 base_vertex_ = 0u;
524 vertex_count_ = 0u;
525 pipeline_ = nullptr;
526 pipeline_uses_input_attachments_ = false;
527 immutable_sampler_ = nullptr;
528 return fml::Status();
529}
std::shared_ptr< PipelineVK > CreateVariantForImmutableSamplers(const std::shared_ptr< SamplerVK > &immutable_sampler) const
const std::shared_ptr< const Context > context_
vk::Image GetImage() const
void InsertBarrierForInputAttachmentRead(const vk::CommandBuffer &buffer, const vk::Image &image)
Inserts the appropriate barriers to ensure that subsequent commands can read from the specified image...

◆ IsValid()

bool impeller::RenderPassVK::IsValid ( ) const
overrideprivatevirtual

Implements impeller::RenderPass.

Definition at line 237 of file render_pass_vk.cc.

237 {
238 return is_valid_;
239}

◆ OnEncodeCommands()

bool impeller::RenderPassVK::OnEncodeCommands ( const Context context) const
overrideprivatevirtual

Implements impeller::RenderPass.

Definition at line 624 of file render_pass_vk.cc.

624 {
625 command_buffer_->GetEncoder()->GetCommandBuffer().endRenderPass();
626
627 // If this render target will be consumed by a subsequent render pass,
628 // perform a layout transition to a shader read state.
629 const std::shared_ptr<Texture>& result_texture =
630 resolve_image_vk_ ? resolve_image_vk_ : color_image_vk_;
631 if (result_texture->GetTextureDescriptor().usage &
633 BarrierVK barrier;
634 barrier.cmd_buffer = command_buffer_vk_;
635 barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite |
636 vk::AccessFlagBits::eTransferWrite;
637 barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput |
638 vk::PipelineStageFlagBits::eTransfer;
639 barrier.dst_access = vk::AccessFlagBits::eShaderRead;
640 barrier.dst_stage = vk::PipelineStageFlagBits::eFragmentShader;
641
642 barrier.new_layout = vk::ImageLayout::eShaderReadOnlyOptimal;
643
644 if (!TextureVK::Cast(*result_texture).SetLayout(barrier)) {
645 return false;
646 }
647 }
648
649 return true;
650}
bool SetLayout(const BarrierVK &barrier) const

◆ OnSetLabel()

void impeller::RenderPassVK::OnSetLabel ( std::string  label)
overrideprivatevirtual

Implements impeller::RenderPass.

Definition at line 241 of file render_pass_vk.cc.

241 {
242#ifdef IMPELLER_DEBUG
243 ContextVK::Cast(*context_).SetDebugName(render_pass_->Get(),
244 std::string(label).c_str());
245#endif // IMPELLER_DEBUG
246}
bool SetDebugName(T handle, std::string_view label) const
Definition context_vk.h:108

◆ ReserveCommands()

void impeller::RenderPassVK::ReserveCommands ( size_t  command_count)
inlineoverrideprivatevirtual

Reserve [command_count] commands in the HAL command buffer.

Note: this is not the native command buffer.

Reimplemented from impeller::RenderPass.

Definition at line 89 of file render_pass_vk.h.

89{}

◆ SetBaseVertex()

void impeller::RenderPassVK::SetBaseVertex ( uint64_t  value)
overrideprivatevirtual

Reimplemented from impeller::RenderPass.

Definition at line 344 of file render_pass_vk.cc.

344 {
345 base_vertex_ = value;
346}
uint8_t value

◆ SetCommandLabel()

void impeller::RenderPassVK::SetCommandLabel ( std::string_view  label)
overrideprivatevirtual

The debugging label to use for the command.

Reimplemented from impeller::RenderPass.

Definition at line 330 of file render_pass_vk.cc.

330 {
331#ifdef IMPELLER_DEBUG
332 command_buffer_->GetEncoder()->PushDebugGroup(label);
333 has_label_ = true;
334#endif // IMPELLER_DEBUG
335}

◆ SetInstanceCount()

void impeller::RenderPassVK::SetInstanceCount ( size_t  count)
overrideprivatevirtual

The number of instances of the given set of vertices to render. Not all backends support rendering more than one instance at a time.

Warning
Setting this to more than one will limit the availability of backends to use with this command.

Reimplemented from impeller::RenderPass.

Definition at line 369 of file render_pass_vk.cc.

369 {
370 instance_count_ = count;
371}
int count

◆ SetPipeline()

void impeller::RenderPassVK::SetPipeline ( const std::shared_ptr< Pipeline< PipelineDescriptor > > &  pipeline)
overrideprivatevirtual

The pipeline to use for this command.

Reimplemented from impeller::RenderPass.

Definition at line 298 of file render_pass_vk.cc.

299 {
300 pipeline_ = pipeline.get();
301 if (!pipeline_) {
302 return;
303 }
304
305 pipeline_uses_input_attachments_ =
306 pipeline_->GetDescriptor().GetVertexDescriptor()->UsesInputAttacments();
307
308 if (pipeline_uses_input_attachments_) {
309 if (bound_image_offset_ >= kMaxBindings) {
310 pipeline_ = nullptr;
311 return;
312 }
313 vk::DescriptorImageInfo image_info;
314 image_info.imageLayout = vk::ImageLayout::eGeneral;
315 image_info.sampler = VK_NULL_HANDLE;
316 image_info.imageView = TextureVK::Cast(*color_image_vk_).GetImageView();
317 image_workspace_[bound_image_offset_++] = image_info;
318
319 vk::WriteDescriptorSet write_set;
320 write_set.dstBinding = kMagicSubpassInputBinding;
321 write_set.descriptorCount = 1u;
322 write_set.descriptorType = vk::DescriptorType::eInputAttachment;
323 write_set.pImageInfo = &image_workspace_[bound_image_offset_ - 1];
324
325 write_workspace_[descriptor_write_offset_++] = write_set;
326 }
327}
const std::shared_ptr< VertexDescriptor > & GetVertexDescriptor() const
const T & GetDescriptor() const
Get the descriptor that was responsible for creating this pipeline. It may be copied and modified to ...
Definition pipeline.cc:49
vk::ImageView GetImageView() const
static constexpr size_t kMagicSubpassInputBinding
#define VK_NULL_HANDLE
Definition vulkan_core.h:46

◆ SetScissor()

void impeller::RenderPassVK::SetScissor ( IRect  scissor)
overrideprivatevirtual

The scissor rect to use for clipping writes to the render target. The scissor rect must lie entirely within the render target. If unset, no scissor is applied.

Reimplemented from impeller::RenderPass.

Definition at line 360 of file render_pass_vk.cc.

360 {
361 vk::Rect2D scissor_vk =
362 vk::Rect2D()
363 .setOffset(vk::Offset2D(scissor.GetX(), scissor.GetY()))
364 .setExtent(vk::Extent2D(scissor.GetWidth(), scissor.GetHeight()));
365 command_buffer_vk_.setScissor(0, 1, &scissor_vk);
366}

◆ SetStencilReference()

void impeller::RenderPassVK::SetStencilReference ( uint32_t  value)
overrideprivatevirtual

The reference value to use in stenciling operations. Stencil configuration is part of pipeline setup and can be read from the pipelines descriptor.

See also
Pipeline
PipelineDescriptor

Reimplemented from impeller::RenderPass.

Definition at line 338 of file render_pass_vk.cc.

338 {
339 command_buffer_vk_.setStencilReference(
340 vk::StencilFaceFlagBits::eVkStencilFrontAndBack, value);
341}

◆ SetVertexBuffer()

bool impeller::RenderPassVK::SetVertexBuffer ( VertexBuffer  buffer)
overrideprivatevirtual

Specify the vertex and index buffer to use for this command.

Parameters
[in]bufferThe vertex and index buffer definition. If possible, this value should be moved and not copied.
Returns
returns if the binding was updated.

Reimplemented from impeller::RenderPass.

Definition at line 374 of file render_pass_vk.cc.

374 {
375 vertex_count_ = buffer.vertex_count;
376 if (buffer.index_type == IndexType::kUnknown || !buffer.vertex_buffer) {
377 return false;
378 }
379
380 if (!command_buffer_->GetEncoder()->Track(buffer.vertex_buffer.buffer)) {
381 return false;
382 }
383
384 // Bind the vertex buffer.
385 vk::Buffer vertex_buffer_handle =
386 DeviceBufferVK::Cast(*buffer.vertex_buffer.buffer).GetBuffer();
387 vk::Buffer vertex_buffers[] = {vertex_buffer_handle};
388 vk::DeviceSize vertex_buffer_offsets[] = {buffer.vertex_buffer.range.offset};
389
390 command_buffer_vk_.bindVertexBuffers(0u, 1u, vertex_buffers,
391 vertex_buffer_offsets);
392
393 // Bind the index buffer.
394 if (buffer.index_type != IndexType::kNone) {
395 has_index_buffer_ = true;
396 const BufferView& index_buffer_view = buffer.index_buffer;
397 if (!index_buffer_view) {
398 return false;
399 }
400
401 const std::shared_ptr<const DeviceBuffer>& index_buffer =
402 index_buffer_view.buffer;
403 if (!index_buffer) {
404 VALIDATION_LOG << "Failed to acquire device buffer"
405 << " for index buffer view";
406 return false;
407 }
408
409 if (!command_buffer_->GetEncoder()->Track(index_buffer)) {
410 return false;
411 }
412
413 vk::Buffer index_buffer_handle =
414 DeviceBufferVK::Cast(*index_buffer).GetBuffer();
415 command_buffer_vk_.bindIndexBuffer(index_buffer_handle,
416 index_buffer_view.range.offset,
417 ToVKIndexType(buffer.index_type));
418 } else {
419 has_index_buffer_ = false;
420 }
421 return true;
422}
vk::Buffer GetBuffer() const
static const uint8_t buffer[]
@ kNone
Does not use the index buffer.
constexpr vk::IndexType ToVKIndexType(IndexType index_type)
Definition formats_vk.h:350
#define VALIDATION_LOG
Definition validation.h:73

◆ SetViewport()

void impeller::RenderPassVK::SetViewport ( Viewport  viewport)
overrideprivatevirtual

The viewport coordinates that the rasterizer linearly maps normalized device coordinates to. If unset, the viewport is the size of the render target with a zero origin, znear=0, and zfar=1.

Reimplemented from impeller::RenderPass.

Definition at line 349 of file render_pass_vk.cc.

349 {
350 vk::Viewport viewport_vk = vk::Viewport()
351 .setWidth(viewport.rect.GetWidth())
352 .setHeight(-viewport.rect.GetHeight())
353 .setY(viewport.rect.GetHeight())
354 .setMinDepth(0.0f)
355 .setMaxDepth(1.0f);
356 command_buffer_vk_.setViewport(0, 1, &viewport_vk);
357}

Friends And Related Symbol Documentation

◆ CommandBufferVK

friend class CommandBufferVK
friend

Definition at line 28 of file render_pass_vk.h.


The documentation for this class was generated from the following files: