// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/renderer/backend/vulkan/render_pass_vk.h"

#include <array>
#include <cstdint>
#include <vector>

#include "fml/status.h"
#include "impeller/base/validation.h"
#include "impeller/core/device_buffer.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture.h"
#include "impeller/renderer/backend/vulkan/barrier_vk.h"
#include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
#include "impeller/renderer/backend/vulkan/command_encoder_vk.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/device_buffer_vk.h"
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/pipeline_vk.h"
#include "impeller/renderer/backend/vulkan/sampler_vk.h"
#include "impeller/renderer/backend/vulkan/shared_object_vk.h"
#include "impeller/renderer/backend/vulkan/texture_vk.h"

#include "vulkan/vulkan_enums.hpp"
#include "vulkan/vulkan_handles.hpp"
#include "vulkan/vulkan_to_string.hpp"

namespace impeller {

// Warning: if any of the constant values or layouts are changed in the
// framebuffer fetch shader, then this input binding may need to be
// manually changed.
//
// See: impeller/entity/shaders/blending/framebuffer_blend.frag
static constexpr size_t kMagicSubpassInputBinding = 64;

static vk::ClearColorValue VKClearValueFromColor(Color color) {
  vk::ClearColorValue value;
  value.setFloat32(
      std::array<float, 4>{color.red, color.green, color.blue, color.alpha});
  return value;
}

static vk::ClearDepthStencilValue VKClearValueFromDepthStencil(uint32_t stencil,
                                                               Scalar depth) {
  vk::ClearDepthStencilValue value;
  value.depth = depth;
  value.stencil = stencil;
  return value;
}

static std::vector<vk::ClearValue> GetVKClearValues(
    const RenderTarget& target) {
  std::vector<vk::ClearValue> clears;

  for (const auto& [_, color] : target.GetColorAttachments()) {
    clears.emplace_back(VKClearValueFromColor(color.clear_color));
    if (color.resolve_texture) {
      clears.emplace_back(VKClearValueFromColor(color.clear_color));
    }
  }

  const auto& depth = target.GetDepthAttachment();
  const auto& stencil = target.GetStencilAttachment();

  if (depth.has_value()) {
    clears.emplace_back(VKClearValueFromDepthStencil(
        stencil ? stencil->clear_stencil : 0u, depth->clear_depth));
  }

  if (stencil.has_value()) {
    clears.emplace_back(VKClearValueFromDepthStencil(
        stencil->clear_stencil, depth ? depth->clear_depth : 0.0f));
  }

  return clears;
}

static vk::AttachmentDescription CreateAttachmentDescription(
    const Attachment& attachment,
    const std::shared_ptr<Texture> Attachment::*texture_ptr,
    bool supports_framebuffer_fetch) {
  const auto& texture = attachment.*texture_ptr;
  if (!texture) {
    return {};
  }
  const auto& texture_vk = TextureVK::Cast(*texture);
  const auto& desc = texture->GetTextureDescriptor();
  auto current_layout = texture_vk.GetLayout();

  auto load_action = attachment.load_action;
  auto store_action = attachment.store_action;

  if (current_layout == vk::ImageLayout::eUndefined) {
    load_action = LoadAction::kClear;
  }

  if (desc.storage_mode == StorageMode::kDeviceTransient) {
    store_action = StoreAction::kDontCare;
  } else if (texture_ptr == &Attachment::resolve_texture) {
    store_action = StoreAction::kStore;
  }

  // Always insert a barrier to transition to color attachment optimal.
  if (current_layout != vk::ImageLayout::ePresentSrcKHR) {
    // Note: This should incur a barrier.
    current_layout = vk::ImageLayout::eGeneral;
  }

  return CreateAttachmentDescription(desc.format,        //
                                     desc.sample_count,  //
                                     load_action,        //
                                     store_action,       //
                                     current_layout,
                                     supports_framebuffer_fetch  //
  );
}

static void SetTextureLayout(
    const Attachment& attachment,
    const vk::AttachmentDescription& attachment_desc,
    const std::shared_ptr<CommandBufferVK>& command_buffer,
    const std::shared_ptr<Texture> Attachment::*texture_ptr) {
  const auto& texture = attachment.*texture_ptr;
  if (!texture) {
    return;
  }
  const auto& texture_vk = TextureVK::Cast(*texture);

  if (attachment_desc.initialLayout == vk::ImageLayout::eGeneral) {
    BarrierVK barrier;
    barrier.new_layout = vk::ImageLayout::eGeneral;
    barrier.cmd_buffer = command_buffer->GetEncoder()->GetCommandBuffer();
    barrier.src_access = vk::AccessFlagBits::eShaderRead;
    barrier.src_stage = vk::PipelineStageFlagBits::eFragmentShader;
    barrier.dst_access = vk::AccessFlagBits::eColorAttachmentWrite |
                         vk::AccessFlagBits::eTransferWrite;
    barrier.dst_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput |
                        vk::PipelineStageFlagBits::eTransfer;

    texture_vk.SetLayout(barrier);
  }

  // Instead of transitioning layouts manually using barriers, we are going to
  // make the subpass perform our transitions.
  texture_vk.SetLayoutWithoutEncoding(attachment_desc.finalLayout);
}

SharedHandleVK<vk::RenderPass> RenderPassVK::CreateVKRenderPass(
    const ContextVK& context,
    const std::shared_ptr<CommandBufferVK>& command_buffer,
    bool supports_framebuffer_fetch) const {
  std::vector<vk::AttachmentDescription> attachments;

  std::vector<vk::AttachmentReference> color_refs;
  std::vector<vk::AttachmentReference> resolve_refs;
  vk::AttachmentReference depth_stencil_ref = kUnusedAttachmentReference;

  // Spec says: "Each element of the pColorAttachments array corresponds to an
  // output location in the shader, i.e. if the shader declares an output
  // variable decorated with a Location value of X, then it uses the attachment
  // provided in pColorAttachments[X]. If the attachment member of any element
  // of pColorAttachments is VK_ATTACHMENT_UNUSED."
  //
  // Just initialize all the elements as unused and fill in the valid bind
  // points in the loop below.
  color_refs.resize(render_target_.GetMaxColorAttacmentBindIndex() + 1u,
                    kUnusedAttachmentReference);
  resolve_refs.resize(render_target_.GetMaxColorAttacmentBindIndex() + 1u,
                      kUnusedAttachmentReference);

  for (const auto& [bind_point, color] : render_target_.GetColorAttachments()) {
    color_refs[bind_point] = vk::AttachmentReference{
        static_cast<uint32_t>(attachments.size()),
        supports_framebuffer_fetch ? vk::ImageLayout::eGeneral
                                   : vk::ImageLayout::eColorAttachmentOptimal};
    attachments.emplace_back(CreateAttachmentDescription(
        color, &Attachment::texture, supports_framebuffer_fetch));
    SetTextureLayout(color, attachments.back(), command_buffer,
                     &Attachment::texture);
    if (color.resolve_texture) {
      resolve_refs[bind_point] = vk::AttachmentReference{
          static_cast<uint32_t>(attachments.size()),
          supports_framebuffer_fetch
              ? vk::ImageLayout::eGeneral
              : vk::ImageLayout::eColorAttachmentOptimal};
      attachments.emplace_back(CreateAttachmentDescription(
          color, &Attachment::resolve_texture, supports_framebuffer_fetch));
      SetTextureLayout(color, attachments.back(), command_buffer,
                       &Attachment::resolve_texture);
    }
  }

  auto depth = render_target_.GetDepthAttachment();
  if (depth.has_value()) {
    depth_stencil_ref = vk::AttachmentReference{
        static_cast<uint32_t>(attachments.size()),
        vk::ImageLayout::eDepthStencilAttachmentOptimal};
    attachments.emplace_back(CreateAttachmentDescription(
        depth.value(), &Attachment::texture, supports_framebuffer_fetch));
    SetTextureLayout(depth.value(), attachments.back(), command_buffer,
                     &Attachment::texture);
  }

  if (auto stencil = render_target_.GetStencilAttachment();
      stencil.has_value()) {
    depth_stencil_ref = vk::AttachmentReference{
        static_cast<uint32_t>(attachments.size()),
        vk::ImageLayout::eDepthStencilAttachmentOptimal};
    attachments.emplace_back(CreateAttachmentDescription(
        stencil.value(), &Attachment::texture, supports_framebuffer_fetch));

    // If the depth and stencil are stored in the same texture, then we've
    // already inserted a memory barrier to transition this texture as part of
    // the depth branch above.
    if (depth.has_value() && depth->texture != stencil->texture) {
      SetTextureLayout(stencil.value(), attachments.back(), command_buffer,
                       &Attachment::texture);
    }
  }

  vk::SubpassDescription subpass_desc;
  subpass_desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
  subpass_desc.setColorAttachments(color_refs);
  subpass_desc.setResolveAttachments(resolve_refs);
  subpass_desc.setPDepthStencilAttachment(&depth_stencil_ref);

  std::vector<vk::SubpassDependency> subpass_dependencies;
  std::vector<vk::AttachmentReference> subpass_color_ref;
  subpass_color_ref.push_back(vk::AttachmentReference{
      static_cast<uint32_t>(0), vk::ImageLayout::eColorAttachmentOptimal});
  if (supports_framebuffer_fetch) {
    subpass_desc.setFlags(vk::SubpassDescriptionFlagBits::
                              eRasterizationOrderAttachmentColorAccessARM);
    subpass_desc.setInputAttachments(subpass_color_ref);
  }

  vk::RenderPassCreateInfo render_pass_desc;
  render_pass_desc.setAttachments(attachments);
  render_pass_desc.setPSubpasses(&subpass_desc);
  render_pass_desc.setSubpassCount(1u);

  auto [result, pass] =
      context.GetDevice().createRenderPassUnique(render_pass_desc);
  if (result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Failed to create render pass: " << vk::to_string(result);
    return {};
  }
  return MakeSharedVK(std::move(pass));
}

RenderPassVK::RenderPassVK(const std::shared_ptr<const Context>& context,
                           const RenderTarget& target,
                           std::shared_ptr<CommandBufferVK> command_buffer)
    : RenderPass(context, target), command_buffer_(std::move(command_buffer)) {
  const auto& vk_context = ContextVK::Cast(*context);
  const std::shared_ptr<CommandEncoderVK>& encoder =
      command_buffer_->GetEncoder();
  command_buffer_vk_ = encoder->GetCommandBuffer();
  render_target_.IterateAllAttachments(
      [&encoder](const auto& attachment) -> bool {
        encoder->Track(attachment.texture);
        encoder->Track(attachment.resolve_texture);
        return true;
      });

  const auto& target_size = render_target_.GetRenderTargetSize();

  render_pass_ = CreateVKRenderPass(
      vk_context, command_buffer_,
      vk_context.GetCapabilities()->SupportsFramebufferFetch());
  if (!render_pass_) {
    VALIDATION_LOG << "Could not create renderpass.";
    is_valid_ = false;
    return;
  }

  auto framebuffer = CreateVKFramebuffer(vk_context, *render_pass_);
  if (!framebuffer) {
    VALIDATION_LOG << "Could not create framebuffer.";
    is_valid_ = false;
    return;
  }

  if (!encoder->Track(framebuffer) || !encoder->Track(render_pass_)) {
    is_valid_ = false;
    return;
  }

  auto clear_values = GetVKClearValues(render_target_);

  vk::RenderPassBeginInfo pass_info;
  pass_info.renderPass = *render_pass_;
  pass_info.framebuffer = *framebuffer;
  pass_info.renderArea.extent.width = static_cast<uint32_t>(target_size.width);
  pass_info.renderArea.extent.height =
      static_cast<uint32_t>(target_size.height);
  pass_info.setClearValues(clear_values);

  command_buffer_vk_.beginRenderPass(pass_info, vk::SubpassContents::eInline);

  // Set the initial viewport and scissors.
  const auto vp = Viewport{.rect = Rect::MakeSize(target_size)};
  vk::Viewport viewport = vk::Viewport()
                              .setWidth(vp.rect.GetWidth())
                              .setHeight(-vp.rect.GetHeight())
                              .setY(vp.rect.GetHeight())
                              .setMinDepth(0.0f)
                              .setMaxDepth(1.0f);
  command_buffer_vk_.setViewport(0, 1, &viewport);

  // Set the initial scissor rect.
  const auto sc = IRect::MakeSize(target_size);
  vk::Rect2D scissor =
      vk::Rect2D()
          .setOffset(vk::Offset2D(sc.GetX(), sc.GetY()))
          .setExtent(vk::Extent2D(sc.GetWidth(), sc.GetHeight()));
  command_buffer_vk_.setScissor(0, 1, &scissor);

  color_image_vk_ =
      render_target_.GetColorAttachments().find(0u)->second.texture;
  resolve_image_vk_ =
      render_target_.GetColorAttachments().find(0u)->second.resolve_texture;
  is_valid_ = true;
}

RenderPassVK::~RenderPassVK() = default;

bool RenderPassVK::IsValid() const {
  return is_valid_;
}

void RenderPassVK::OnSetLabel(std::string label) {
#ifdef IMPELLER_DEBUG
  ContextVK::Cast(*context_).SetDebugName(render_pass_->Get(),
                                          std::string(label).c_str());
#endif  // IMPELLER_DEBUG
}

SharedHandleVK<vk::Framebuffer> RenderPassVK::CreateVKFramebuffer(
    const ContextVK& context,
    const vk::RenderPass& pass) const {
  vk::FramebufferCreateInfo fb_info;

  fb_info.renderPass = pass;

  const auto target_size = render_target_.GetRenderTargetSize();
  fb_info.width = target_size.width;
  fb_info.height = target_size.height;
  fb_info.layers = 1u;

  std::vector<vk::ImageView> attachments;

  // This bit must be consistent to ensure compatibility with the pass created
  // earlier. Follow this order: Color attachments, then depth, then stencil.
  for (const auto& [_, color] : render_target_.GetColorAttachments()) {
    // The bind point doesn't matter here since that information is present in
    // the render pass.
    attachments.emplace_back(
        TextureVK::Cast(*color.texture).GetRenderTargetView());
    if (color.resolve_texture) {
      attachments.emplace_back(
          TextureVK::Cast(*color.resolve_texture).GetRenderTargetView());
    }
  }
  if (auto depth = render_target_.GetDepthAttachment(); depth.has_value()) {
    attachments.emplace_back(
        TextureVK::Cast(*depth->texture).GetRenderTargetView());
  }
  if (auto stencil = render_target_.GetStencilAttachment();
      stencil.has_value()) {
    attachments.emplace_back(
        TextureVK::Cast(*stencil->texture).GetRenderTargetView());
  }

  fb_info.setAttachments(attachments);

  auto [result, framebuffer] =
      context.GetDevice().createFramebufferUnique(fb_info);

  if (result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Could not create framebuffer: " << vk::to_string(result);
    return {};
  }

  return MakeSharedVK(std::move(framebuffer));
}

// |RenderPass|
void RenderPassVK::SetPipeline(
    const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
  PipelineVK& pipeline_vk = PipelineVK::Cast(*pipeline);

  auto descriptor_result =
      command_buffer_->GetEncoder()->AllocateDescriptorSets(
          pipeline_vk.GetDescriptorSetLayout(), ContextVK::Cast(*context_));
  if (!descriptor_result.ok()) {
    return;
  }
  pipeline_valid_ = true;
  descriptor_set_ = descriptor_result.value();
  pipeline_layout_ = pipeline_vk.GetPipelineLayout();
  command_buffer_vk_.bindPipeline(vk::PipelineBindPoint::eGraphics,
                                  pipeline_vk.GetPipeline());

  if (pipeline->GetDescriptor().UsesSubpassInput()) {
    if (bound_image_offset_ >= kMaxBindings) {
      pipeline_valid_ = false;
      return;
    }

    vk::DescriptorImageInfo image_info;
    image_info.imageLayout = vk::ImageLayout::eGeneral;
    image_info.sampler = VK_NULL_HANDLE;
    image_info.imageView = TextureVK::Cast(*color_image_vk_).GetImageView();
    image_workspace_[bound_image_offset_++] = image_info;

    vk::WriteDescriptorSet write_set;
    write_set.dstBinding = kMagicSubpassInputBinding;
    write_set.descriptorCount = 1u;
    write_set.descriptorType = vk::DescriptorType::eInputAttachment;
    write_set.pImageInfo = &image_workspace_[bound_image_offset_ - 1];

    write_workspace_[descriptor_write_offset_++] = write_set;
  }
}

// |RenderPass|
void RenderPassVK::SetCommandLabel(std::string_view label) {
#ifdef IMPELLER_DEBUG
  command_buffer_->GetEncoder()->PushDebugGroup(label);
  has_label_ = true;
#endif  // IMPELLER_DEBUG
}

// |RenderPass|
void RenderPassVK::SetStencilReference(uint32_t value) {
  command_buffer_vk_.setStencilReference(
      vk::StencilFaceFlagBits::eVkStencilFrontAndBack, value);
}

// |RenderPass|
void RenderPassVK::SetBaseVertex(uint64_t value) {
  base_vertex_ = value;
}

// |RenderPass|
void RenderPassVK::SetViewport(Viewport viewport) {
  vk::Viewport viewport_vk = vk::Viewport()
                                 .setWidth(viewport.rect.GetWidth())
                                 .setHeight(-viewport.rect.GetHeight())
                                 .setY(viewport.rect.GetHeight())
                                 .setMinDepth(0.0f)
                                 .setMaxDepth(1.0f);
  command_buffer_vk_.setViewport(0, 1, &viewport_vk);
}

// |RenderPass|
void RenderPassVK::SetScissor(IRect scissor) {
  vk::Rect2D scissor_vk =
      vk::Rect2D()
          .setOffset(vk::Offset2D(scissor.GetX(), scissor.GetY()))
          .setExtent(vk::Extent2D(scissor.GetWidth(), scissor.GetHeight()));
  command_buffer_vk_.setScissor(0, 1, &scissor_vk);
}

// |RenderPass|
void RenderPassVK::SetInstanceCount(size_t count) {
  instance_count_ = count;
}

// |RenderPass|
bool RenderPassVK::SetVertexBuffer(VertexBuffer buffer) {
  vertex_count_ = buffer.vertex_count;
  if (buffer.index_type == IndexType::kUnknown || !buffer.vertex_buffer) {
    return false;
  }

  if (!command_buffer_->GetEncoder()->Track(buffer.vertex_buffer.buffer)) {
    return false;
  }

  // Bind the vertex buffer.
  vk::Buffer vertex_buffer_handle =
      DeviceBufferVK::Cast(*buffer.vertex_buffer.buffer).GetBuffer();
  vk::Buffer vertex_buffers[] = {vertex_buffer_handle};
  vk::DeviceSize vertex_buffer_offsets[] = {buffer.vertex_buffer.range.offset};

  command_buffer_vk_.bindVertexBuffers(0u, 1u, vertex_buffers,
                                       vertex_buffer_offsets);

  // Bind the index buffer.
  if (buffer.index_type != IndexType::kNone) {
    has_index_buffer_ = true;
    const BufferView& index_buffer_view = buffer.index_buffer;
    if (!index_buffer_view) {
      return false;
    }

    const std::shared_ptr<const DeviceBuffer>& index_buffer =
        index_buffer_view.buffer;
    if (!index_buffer) {
      VALIDATION_LOG << "Failed to acquire device buffer"
                     << " for index buffer view";
      return false;
    }

    if (!command_buffer_->GetEncoder()->Track(index_buffer)) {
      return false;
    }

    vk::Buffer index_buffer_handle =
        DeviceBufferVK::Cast(*index_buffer).GetBuffer();
    command_buffer_vk_.bindIndexBuffer(index_buffer_handle,
                                       index_buffer_view.range.offset,
                                       ToVKIndexType(buffer.index_type));
  } else {
    has_index_buffer_ = false;
  }
  return true;
}

// |RenderPass|
fml::Status RenderPassVK::Draw() {
  if (!pipeline_valid_) {
    return fml::Status(fml::StatusCode::kCancelled,
                       "No valid pipeline is bound to the RenderPass.");
  }

  const ContextVK& context_vk = ContextVK::Cast(*context_);
  for (auto i = 0u; i < descriptor_write_offset_; i++) {
    write_workspace_[i].dstSet = descriptor_set_;
  }

  context_vk.GetDevice().updateDescriptorSets(descriptor_write_offset_,
                                              write_workspace_.data(), 0u, {});

  command_buffer_vk_.bindDescriptorSets(
      vk::PipelineBindPoint::eGraphics,  // bind point
      pipeline_layout_,                  // layout
      0,                                 // first set
      1,                                 // set count
      &descriptor_set_,                  // sets
      0,                                 // offset count
      nullptr                            // offsets
  );

  if (has_index_buffer_) {
    command_buffer_vk_.drawIndexed(vertex_count_,    // index count
                                   instance_count_,  // instance count
                                   0u,               // first index
                                   base_vertex_,     // vertex offset
                                   0u                // first instance
    );
  } else {
    command_buffer_vk_.draw(vertex_count_,    // vertex count
                            instance_count_,  // instance count
                            base_vertex_,     // vertex offset
                            0u                // first instance
    );
  }

#ifdef IMPELLER_DEBUG
  if (has_label_) {
    command_buffer_->GetEncoder()->PopDebugGroup();
  }
#endif  // IMPELLER_DEBUG
  has_label_ = false;
  has_index_buffer_ = false;
  bound_image_offset_ = 0u;
  bound_buffer_offset_ = 0u;
  descriptor_write_offset_ = 0u;
  instance_count_ = 1u;
  base_vertex_ = 0u;
  vertex_count_ = 0u;
  pipeline_valid_ = false;
  return fml::Status();
}

// The RenderPassVK binding methods only need the binding, set, and buffer type
// information.
bool RenderPassVK::BindResource(ShaderStage stage,
                                DescriptorType type,
                                const ShaderUniformSlot& slot,
                                const ShaderMetadata& metadata,
                                BufferView view) {
  return BindResource(slot.binding, type, view);
}

bool RenderPassVK::BindResource(
    ShaderStage stage,
    DescriptorType type,
    const ShaderUniformSlot& slot,
    const std::shared_ptr<const ShaderMetadata>& metadata,
    BufferView view) {
  return BindResource(slot.binding, type, view);
}

bool RenderPassVK::BindResource(size_t binding,
                                DescriptorType type,
                                const BufferView& view) {
  if (bound_buffer_offset_ >= kMaxBindings) {
    return false;
  }

  const std::shared_ptr<const DeviceBuffer>& device_buffer = view.buffer;
  auto buffer = DeviceBufferVK::Cast(*device_buffer).GetBuffer();
  if (!buffer) {
    return false;
  }

  if (!command_buffer_->GetEncoder()->Track(device_buffer)) {
    return false;
  }

  uint32_t offset = view.range.offset;

  vk::DescriptorBufferInfo buffer_info;
  buffer_info.buffer = buffer;
  buffer_info.offset = offset;
  buffer_info.range = view.range.length;
  buffer_workspace_[bound_buffer_offset_++] = buffer_info;

  vk::WriteDescriptorSet write_set;
  write_set.dstBinding = binding;
  write_set.descriptorCount = 1u;
  write_set.descriptorType = ToVKDescriptorType(type);
  write_set.pBufferInfo = &buffer_workspace_[bound_buffer_offset_ - 1];

  write_workspace_[descriptor_write_offset_++] = write_set;
  return true;
}

bool 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) {
  if (bound_buffer_offset_ >= kMaxBindings) {
    return false;
  }
  if (!texture->IsValid() || !sampler) {
    return false;
  }
  const TextureVK& texture_vk = TextureVK::Cast(*texture);
  const SamplerVK& sampler_vk = SamplerVK::Cast(*sampler);

  if (!command_buffer_->GetEncoder()->Track(texture)) {
    return false;
  }

  vk::DescriptorImageInfo image_info;
  image_info.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
  image_info.sampler = sampler_vk.GetSampler();
  image_info.imageView = texture_vk.GetImageView();
  image_workspace_[bound_image_offset_++] = image_info;

  vk::WriteDescriptorSet write_set;
  write_set.dstBinding = slot.binding;
  write_set.descriptorCount = 1u;
  write_set.descriptorType = vk::DescriptorType::eCombinedImageSampler;
  write_set.pImageInfo = &image_workspace_[bound_image_offset_ - 1];

  write_workspace_[descriptor_write_offset_++] = write_set;
  return true;
}

bool RenderPassVK::OnEncodeCommands(const Context& context) const {
  command_buffer_->GetEncoder()->GetCommandBuffer().endRenderPass();

  // If this render target will be consumed by a subsequent render pass,
  // perform a layout transition to a shader read state.
  const std::shared_ptr<Texture>& result_texture =
      resolve_image_vk_ ? resolve_image_vk_ : color_image_vk_;
  if (result_texture->GetTextureDescriptor().usage &
      static_cast<TextureUsageMask>(TextureUsage::kShaderRead)) {
    BarrierVK barrier;
    barrier.cmd_buffer = command_buffer_vk_;
    barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite |
                         vk::AccessFlagBits::eTransferWrite;
    barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput |
                        vk::PipelineStageFlagBits::eTransfer;
    barrier.dst_access = vk::AccessFlagBits::eShaderRead;
    barrier.dst_stage = vk::PipelineStageFlagBits::eFragmentShader;

    barrier.new_layout = vk::ImageLayout::eShaderReadOnlyOptimal;

    if (!TextureVK::Cast(*result_texture).SetLayout(barrier)) {
      return false;
    }
  }

  return true;
}

}  // namespace impeller
