// Copyright 2018 The Fuchsia 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 "src/ui/lib/escher/paper/paper_renderer.h"

#include <glm/gtc/matrix_access.hpp>
#include <vulkan/vulkan.hpp>

// TODO(fxbug.dev/7244): possibly delete.  See comment below about NUM_CLIP_PLANES.
#include "src/ui/lib/escher/debug/debug_font.h"
#include "src/ui/lib/escher/debug/debug_rects.h"
#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/mesh/tessellation.h"
#include "src/ui/lib/escher/paper/paper_render_queue_context.h"
#include "src/ui/lib/escher/paper/paper_renderer_static_config.h"
#include "src/ui/lib/escher/paper/paper_scene.h"
#include "src/ui/lib/escher/paper/paper_shader_structs.h"
#include "src/ui/lib/escher/renderer/batch_gpu_uploader.h"
#include "src/ui/lib/escher/renderer/render_funcs.h"
#include "src/ui/lib/escher/scene/object.h"
// TODO(fxbug.dev/44894): try to avoid including an "impl" file.
#include "src/ui/lib/escher/third_party/granite/vk/command_buffer_pipeline_state.h"
#include "src/ui/lib/escher/third_party/granite/vk/render_pass.h"
#include "src/ui/lib/escher/util/string_utils.h"
#include "src/ui/lib/escher/util/trace_macros.h"
#include "src/ui/lib/escher/vk/command_buffer.h"
#include "src/ui/lib/escher/vk/image.h"
#include "src/ui/lib/escher/vk/impl/render_pass_cache.h"
#include "src/ui/lib/escher/vk/pipeline_builder.h"
#include "src/ui/lib/escher/vk/render_pass_info.h"
#include "src/ui/lib/escher/vk/shader_program.h"
#include "src/ui/lib/escher/vk/texture.h"

namespace escher {

PaperRendererPtr PaperRenderer::New(EscherWeakPtr escher, const PaperRendererConfig& config) {
  return fxl::AdoptRef(new PaperRenderer(std::move(escher), config));
}

PaperRenderer::PaperRenderer(EscherWeakPtr weak_escher, const PaperRendererConfig& config)
    : escher_(weak_escher),
      context_(weak_escher->vulkan_context()),
      config_(config),
      draw_call_factory_(weak_escher, config),
      shape_cache_(std::move(weak_escher), config),
      // TODO(fxbug.dev/7242): (probably) move programs into PaperDrawCallFactory.
      ambient_light_program_(escher()->GetProgram(kAmbientLightProgramData)),
      no_lighting_program_(escher()->GetProgram(kNoLightingProgramData)),
      point_light_program_(escher()->GetProgram(kPointLightProgramData)),
      point_light_falloff_program_(escher()->GetProgram(kPointLightFalloffProgramData)),
      shadow_volume_geometry_program_(escher()->GetProgram(kShadowVolumeGeometryProgramData)),
      shadow_volume_geometry_debug_program_(
          escher()->GetProgram(kShadowVolumeGeometryDebugProgramData)) {
  FX_DCHECK(config.num_depth_buffers > 0);
  depth_buffers_.resize(config.num_depth_buffers);
  msaa_buffers_.resize(config.num_depth_buffers);
}

PaperRenderer::~PaperRenderer() = default;

PaperRenderer::FrameData::FrameData(const FramePtr& frame_in,
                                    std::shared_ptr<BatchGpuUploader> gpu_uploader_in,
                                    const PaperScenePtr& scene_in, const ImagePtr& output_image_in,
                                    std::pair<TexturePtr, TexturePtr> depth_and_msaa_textures,
                                    const std::vector<Camera>& cameras_in)
    : frame(frame_in),
      output_image(output_image_in),
      depth_texture(depth_and_msaa_textures.first),
      msaa_texture(depth_and_msaa_textures.second),
      gpu_uploader(gpu_uploader_in),
      scene(scene_in) {
  // Scale the camera viewports to pixel coordinates in the output framebuffer.
  for (auto& cam : cameras_in) {
    vk::Rect2D rect = cam.viewport().vk_rect_2d(output_image->width(), output_image->height());
    vk::Viewport viewport(static_cast<float>(rect.offset.x), static_cast<float>(rect.offset.y),
                          static_cast<float>(rect.extent.width),
                          static_cast<float>(rect.extent.height), 0, 1);

    UniformBinding binding;
    CameraEye eye = CameraEye::kLeft;
    if (auto buffer = cam.latched_pose_buffer()) {
      // The camera has a latched pose-buffer, so we use it to obtain a
      // view-projection matrix in the shader.  We pass the eye_index as a
      // push-constant to obtain the correct matrix.
      frame->cmds()->KeepAlive(buffer);
      binding.descriptor_set_index = PaperShaderLatchedPoseBuffer::kDescriptorSet;
      binding.binding_index = PaperShaderLatchedPoseBuffer::kDescriptorBinding;
      binding.buffer = buffer.get();
      binding.offset = 0;
      binding.size = sizeof(PaperShaderLatchedPoseBuffer);
      eye = cam.latched_camera_eye();
    } else {
      // The camera has no latched pose-buffer, so allocate/populate uniform
      // data with the same layout, based on the camera's projection/transform
      // matrices.
      auto pair = NewPaperShaderUniformBinding<PaperShaderLatchedPoseBuffer>(frame);
      pair.first->vp_matrix[0] = cam.projection() * cam.transform();
      pair.first->vp_matrix[1] = cam.projection() * cam.transform();
      binding = pair.second;
    }

    cameras.push_back({.binding = binding,
                       .rect = rect,
                       .viewport = viewport,
                       .eye_index = (eye == CameraEye::kLeft ? 0U : 1U)});
  }

  // Generate a UniformBinding for global scene data (e.g. ambient lighting).
  {
    auto writable_binding = NewPaperShaderUniformBinding<PaperShaderSceneData>(frame);
    writable_binding.first->ambient_light_color = scene->ambient_light.color;
    scene_uniform_bindings.push_back(writable_binding.second);
  }

  // Generate a UniformBinding containing data for all point lights, if any.
  auto num_lights = scene->num_point_lights();
  if (num_lights > 0) {
    auto writable_binding = NewPaperShaderUniformBinding<PaperShaderPointLight>(frame, num_lights);
    auto* point_lights = writable_binding.first;
    for (size_t i = 0; i < num_lights; ++i) {
      const PaperPointLight& light = scene->point_lights[i];
      point_lights[i].position = vec4(light.position, 1);
      point_lights[i].color = vec4(light.color, 1);
      point_lights[i].falloff = light.falloff;
    }
    scene_uniform_bindings.push_back(writable_binding.second);
  }
}

PaperRenderer::FrameData::~FrameData() = default;

void PaperRenderer::SetConfig(const PaperRendererConfig& config) {
  FX_DCHECK(!frame_data_) << "Illegal call to SetConfig() during a frame.";
  FX_DCHECK(SupportsShadowType(config.shadow_type))
      << "Unsupported shadow type: " << config.shadow_type;
  FX_DCHECK(config.num_depth_buffers > 0);
  FX_DCHECK(config.msaa_sample_count == 1 || config.msaa_sample_count == 2 ||
            config.msaa_sample_count == 4);

  const auto& supported_sample_counts = escher()->device()->caps().msaa_sample_counts;
  if (supported_sample_counts.find(config.msaa_sample_count) == supported_sample_counts.end()) {
    FX_LOGS(ERROR) << "PaperRenderer: MSAA sample count ("
                   << static_cast<uint32_t>(config.msaa_sample_count)
                   << ") is not supported on this device. SetConfig failed.";
    return;
  }
  if (escher()
          ->device()
          ->caps()
          .GetMatchingDepthStencilFormat({config.depth_stencil_format})
          .result != vk::Result::eSuccess) {
    FX_LOGS(ERROR) << "PaperRenderer: Depth stencil format ("
                   << vk::to_string(config.depth_stencil_format)
                   << ") is not supported on this device. SetConfig failed.";
    return;
  }

  if (config.msaa_sample_count != config_.msaa_sample_count) {
    FX_VLOGS(1) << "PaperRenderer: MSAA sample count set to: " << config.msaa_sample_count
                << " (was: " << config_.msaa_sample_count << ")";
    depth_buffers_.clear();
    msaa_buffers_.clear();
  }

  if (config.depth_stencil_format != config_.depth_stencil_format) {
    FX_VLOGS(1) << "PaperRenderer: depth_stencil_format set to: "
                << vk::to_string(config.depth_stencil_format)
                << " (was: " << vk::to_string(config_.depth_stencil_format) << ")";
    depth_buffers_.clear();
  }

  if (config.num_depth_buffers != config_.num_depth_buffers) {
    FX_VLOGS(1) << "PaperRenderer: num_depth_buffers set to: " << config.num_depth_buffers
                << " (was: " << config_.num_depth_buffers << ")";
  }
  // This is done here (instead of the if-statement above) because there may
  // have been a change to the MSAA sample count.
  depth_buffers_.resize(config.num_depth_buffers);
  msaa_buffers_.resize(config.num_depth_buffers);

  config_ = config;

  draw_call_factory_.SetConfig(config_);
  shape_cache_.SetConfig(config_);
}

bool PaperRenderer::SupportsShadowType(PaperRendererShadowType shadow_type) const {
  return shadow_type == PaperRendererShadowType::kNone ||
         shadow_type == PaperRendererShadowType::kShadowVolume;
}

void PaperRenderer::BeginFrame(const FramePtr& frame, std::shared_ptr<BatchGpuUploader> uploader,
                               const PaperScenePtr& scene, const std::vector<Camera>& cameras,
                               const ImagePtr& output_image) {
  TRACE_DURATION("gfx", "PaperRenderer::BeginFrame");
  FX_DCHECK(!frame_data_) << "already in a frame.";
  FX_DCHECK(frame && uploader && scene && !cameras.empty() && output_image);

  auto index = frame->frame_number() % depth_buffers_.size();
  TexturePtr& depth_texture = depth_buffers_[index];
  TexturePtr& msaa_texture = msaa_buffers_[index];
  RenderFuncs::ObtainDepthAndMsaaTextures(escher(), frame, output_image->info(),
                                          config_.msaa_sample_count, config_.depth_stencil_format,
                                          depth_texture, msaa_texture);

  frame_data_ = std::make_unique<FrameData>(
      frame, std::move(uploader), scene, output_image,
      std::pair<TexturePtr, TexturePtr>(depth_texture, msaa_texture), cameras);

  shape_cache_.BeginFrame(frame_data_->gpu_uploader.get(), frame->frame_number());

  {
    // As described in the header file, we use the first camera's transform for
    // the purpose of depth-sorting.
    mat4 camera_transform = cameras[0].transform();

    // A camera's transform doesn't move the camera; it is applied to the rest
    // of the scene to "move it away from the camera".  Therefore, the camera's
    // position in the scene can be obtained by inverting it and applying it to
    // the origin, or equivalently by inverting the transform and taking the
    // rightmost (translation) column.
    vec3 camera_pos(glm::column(glm::inverse(camera_transform), 3));

    // The camera points down the negative-Z axis, so its world-space direction
    // can be obtained by applying the camera transform to the direction vector
    // [0, 0, -1, 0] (remembering that directions vectors have a w-coord of 0,
    // vs. 1 for position vectors).  This is equivalent to taking the negated
    // third column of the transform.
    vec3 camera_dir = -vec3(glm::column(camera_transform, 2));

    draw_call_factory_.BeginFrame(frame, frame_data_->gpu_uploader.get(), scene.get(),
                                  &transform_stack_, &render_queue_, &shape_cache_, camera_pos,
                                  camera_dir);
  }
}

void PaperRenderer::FinalizeFrame() {
  TRACE_DURATION("gfx", "PaperRenderer::FinalizeFrame");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized && frame_data_->gpu_uploader);

  // We may need to lazily instantiate |debug_font|, or delete it. If the former, this needs to be
  // done before we submit the GPU uploader's tasks.

  // TODO(fxbug.dev/7313): Clean up lazy instantiation. Right now, DebugFont and DebugRects are
  // created/destroyed from frame-to-frame.
  if (config_.debug_frame_number) {
    DrawDebugText(std::to_string(frame_data_->frame->frame_number()), {10, 10}, 4);
  }
  if (!frame_data_->texts.empty()) {
    if (!debug_font_) {
      debug_font_ = DebugFont::New(frame_data_->gpu_uploader.get(), escher()->image_cache());
    }
  } else {
    debug_font_.reset();
  }

  if (!frame_data_->lines.empty()) {
    if (!debug_lines_) {
      debug_lines_ = DebugRects::New(frame_data_->gpu_uploader.get(), escher()->image_cache());
    }
  } else {
    debug_lines_.reset();
  }

  // At this point, all uploads are finished, and no Vulkan commands that depend on these
  // uploads have yet been generated.  After this point, no additional uploads are allowed.
  frame_data_->scene_finalized = true;
  frame_data_->gpu_uploader.reset();
}

void PaperRenderer::EndFrame(const std::vector<SemaphorePtr>& upload_wait_semaphores) {
  TRACE_DURATION("gfx", "PaperRenderer::EndFrame");
  FX_DCHECK(frame_data_);
  FX_DCHECK(frame_data_->scene_finalized && !frame_data_->gpu_uploader);

  for (const SemaphorePtr& upload_wait_semaphore : upload_wait_semaphores) {
    frame_data_->frame->cmds()->AddWaitSemaphore(
        std::move(upload_wait_semaphore), vk::PipelineStageFlagBits::eVertexInput |
                                              vk::PipelineStageFlagBits::eFragmentShader |
                                              vk::PipelineStageFlagBits::eColorAttachmentOutput |
                                              vk::PipelineStageFlagBits::eTransfer);
  }

  // Generate the Vulkan commands to render the frame.
  render_queue_.Sort();
  {
    for (uint32_t camera_index = 0; camera_index < frame_data_->cameras.size(); ++camera_index) {
      switch (config_.shadow_type) {
        case PaperRendererShadowType::kNone:
          GenerateCommandsForNoShadows(camera_index);
          break;
        case PaperRendererShadowType::kShadowVolume:
          GenerateCommandsForShadowVolumes(camera_index);
          break;
        default:
          FX_DCHECK(false) << "Unsupported shadow type: " << config_.shadow_type;
          GenerateCommandsForNoShadows(camera_index);
      }
    }
  }
  render_queue_.Clear();

  GenerateDebugCommands(frame_data_->frame->cmds());

  frame_data_ = nullptr;
  transform_stack_.Clear();
  shape_cache_.EndFrame();
  draw_call_factory_.EndFrame();
}

void PaperRenderer::DrawDebugText(std::string text, vk::Offset2D offset, int32_t scale) {
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  // TODO(fxbug.dev/7334): Add error checking to make sure math will not cause negative
  // values or the bars to go off screen.
  frame_data_->texts.push_back({text, offset, scale});
}

void PaperRenderer::DrawVLine(escher::DebugRects::Color kColor, uint32_t x_coord, int32_t y_start,
                              uint32_t y_end, uint32_t thickness) {
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  vk::Rect2D rect;
  vk::Offset2D offset = {static_cast<int32_t>(x_coord), y_start};
  vk::Extent2D extent = {static_cast<uint32_t>(x_coord + thickness), y_end};

  // Adds error checking to make sure math will not cause negative
  // values or the bars to go off screen.
  FX_DCHECK(extent.width >= 0 && extent.width < frame_data_->output_image->width());
  FX_DCHECK(extent.height >= 0 && extent.height < frame_data_->output_image->height());

  rect.offset = offset;
  rect.extent = extent;

  frame_data_->lines.push_back({kColor, rect});
}

void PaperRenderer::DrawHLine(escher::DebugRects::Color kColor, int32_t y_coord, int32_t x_start,
                              uint32_t x_end, int32_t thickness) {
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  vk::Rect2D rect;
  vk::Offset2D offset = {x_start, static_cast<int32_t>(y_coord)};
  vk::Extent2D extent = {x_end, static_cast<uint32_t>(y_coord + thickness)};

  // Adds error checking to make sure math will not cause negative
  // values or the bars to go off screen.
  FX_DCHECK(extent.width >= 0 && extent.width < frame_data_->output_image->width());
  FX_DCHECK(extent.height >= 0 && extent.height < frame_data_->output_image->height());

  rect.offset = offset;
  rect.extent = extent;

  frame_data_->lines.push_back({kColor, rect});
}

void PaperRenderer::BindSceneAndCameraUniforms(uint32_t camera_index) {
  auto* cmd_buf = frame_data_->frame->cmds();
  for (UniformBinding& binding : frame_data_->scene_uniform_bindings) {
    binding.Bind(cmd_buf);
  }
  frame_data_->cameras[camera_index].binding.Bind(cmd_buf);
}

bool PaperRenderer::SupportsMaterial(const PaperMaterialPtr& material) {
  if (!material) {
    return false;
  }
  if (material->type() == Material::Type::kWireframe && !escher()->supports_wireframe()) {
    FX_LOGS(ERROR) << "Device doesn't support feature fillModeNonSolid. "
                      "Draw Calls will not be enqueued.";
    return false;
  }
  return true;
}

void PaperRenderer::Draw(PaperDrawable* drawable, PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::Draw");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  // For restoring state afterward.
  size_t transform_stack_size = transform_stack_.size();
  size_t num_clip_planes = transform_stack_.num_clip_planes();
  drawable->DrawInScene(frame_data_->scene.get(), &draw_call_factory_, &transform_stack_,
                        frame_data_->frame.get(), flags);
  transform_stack_.Clear({transform_stack_size, num_clip_planes});
}

void PaperRenderer::DrawCircle(float radius, const PaperMaterialPtr& material,
                               PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::DrawCircle");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  FX_DCHECK(material);
  if (!SupportsMaterial(material)) {
    return;
  }
  draw_call_factory_.DrawCircle(radius, *material.get(), flags);
}

void PaperRenderer::DrawRect(vec2 min, vec2 max, const PaperMaterialPtr& material,
                             PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::DrawRect");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  FX_DCHECK(material);
  if (!SupportsMaterial(material)) {
    return;
  }
  draw_call_factory_.DrawRect(min, max, *material.get(), flags);
}

// Convenience wrapper around the standard DrawRect function.
void PaperRenderer::DrawRect(float width, float height, const PaperMaterialPtr& material,
                             PaperDrawableFlags flags) {
  const vec2 extent(width, height);
  DrawRect(-0.5f * extent, 0.5f * extent, material, flags);
}

void PaperRenderer::DrawRoundedRect(const RoundedRectSpec& spec, const PaperMaterialPtr& material,
                                    PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::DrawRoundedRect");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  FX_DCHECK(material);
  if (!SupportsMaterial(material)) {
    return;
  }
  draw_call_factory_.DrawRoundedRect(spec, *material.get(), flags);
}

void PaperRenderer::DrawBoundingBox(const BoundingBox& box, const PaperMaterialPtr& material,
                                    PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::DrawBoundingBox");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  FX_DCHECK(material);
  if (!SupportsMaterial(material)) {
    return;
  }
  if (material->texture()) {
    FX_LOGS(ERROR) << "TODO(fxbug.dev/7307): Box meshes do not currently support textures.";
    return;
  }

  mat4 matrix = box.CreateTransform();
  transform_stack_.PushTransform(matrix);
  draw_call_factory_.DrawBoundingBox(*material.get(), flags);
  transform_stack_.Pop();
}

void PaperRenderer::DrawMesh(const MeshPtr& mesh, const PaperMaterialPtr& material,
                             PaperDrawableFlags flags) {
  TRACE_DURATION("gfx", "PaperRenderer::DrawMesh");
  FX_DCHECK(frame_data_);
  FX_DCHECK(!frame_data_->scene_finalized);

  FX_DCHECK(material);
  if (!SupportsMaterial(material)) {
    return;
  }
  draw_call_factory_.DrawMesh(mesh, *material.get(), flags);
}

// TODO(fxbug.dev/7245): in "no shadows" mode, should we:
// - not use the other lights, and boost the ambient intensity?
// - still use the lights, allowing a BRDF, distance-based-falloff etc.
// The right answer is probably to separate the shadow algorithm from the
// lighting model.
void PaperRenderer::GenerateCommandsForNoShadows(uint32_t camera_index) {
  TRACE_DURATION("gfx", "PaperRenderer::GenerateCommandsForNoShadows");

  const FramePtr& frame = frame_data_->frame;
  CommandBuffer* cmd_buf = frame->cmds();

  RenderPassInfo render_pass_info;
  FX_DCHECK(camera_index < frame_data_->cameras.size());
  auto render_area = frame_data_->cameras[camera_index].rect;

  if (!RenderPassInfo::InitRenderPassInfo(&render_pass_info, render_area, frame_data_->output_image,
                                          frame_data_->depth_texture, frame_data_->msaa_texture,
                                          escher()->image_view_allocator())) {
    FX_LOGS(ERROR) << "PaperRenderer::GenerateCommandsForNoShadows(): "
                      "RenderPassInfo initialization failed. Exiting.";
    return;
  }

  cmd_buf->BeginRenderPass(render_pass_info);
  frame->AddTimestamp("started no-shadows render pass");

  BindSceneAndCameraUniforms(camera_index);

  const CameraData& cam_data = frame_data_->cameras[camera_index];
  cmd_buf->SetViewport(cam_data.viewport);
  cmd_buf->PushConstants(PaperShaderPushConstants{
      .light_index = 0,  // ignored
      .eye_index = cam_data.eye_index,
  });

  {
    PaperRenderQueueContext context;
    context.set_draw_mode(PaperRendererDrawMode::kAmbient);

    // Render wireframe.
    context.set_shader_program(no_lighting_program_);
    cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kWireframe);
    render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kWireframe);

    // Render opaque.
    context.set_shader_program(ambient_light_program_);
    cmd_buf->SetWireframe(false);
    cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kOpaque);
    render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kOpaque);

    // Render translucent.
    context.set_shader_program(no_lighting_program_);
    cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kTranslucent);
    render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kTranslucent);
  }
  cmd_buf->EndRenderPass();
  frame->AddTimestamp("finished no-shadows render pass");
}

void PaperRenderer::GenerateCommandsForShadowVolumes(uint32_t camera_index) {
  TRACE_DURATION("gfx", "PaperRenderer::GenerateCommandsForShadowVolumes");

  const uint32_t width = frame_data_->output_image->width();
  const uint32_t height = frame_data_->output_image->height();
  const FramePtr& frame = frame_data_->frame;
  CommandBuffer* cmd_buf = frame->cmds();

  RenderPassInfo render_pass_info;
  FX_DCHECK(camera_index < frame_data_->cameras.size());
  auto render_area = frame_data_->cameras[camera_index].rect;

  if (!RenderPassInfo::InitRenderPassInfo(&render_pass_info, render_area, frame_data_->output_image,
                                          frame_data_->depth_texture, frame_data_->msaa_texture,
                                          escher()->image_view_allocator())) {
    FX_LOGS(ERROR) << "PaperRenderer::GenerateCommandsForShadowVolumes(): "
                      "RenderPassInfo initialization failed. Exiting.";
    return;
  }

  cmd_buf->BeginRenderPass(render_pass_info);
  frame->AddTimestamp("started shadow_volume render pass");

  BindSceneAndCameraUniforms(camera_index);

  const CameraData& cam_data = frame_data_->cameras[camera_index];
  cmd_buf->SetViewport(cam_data.viewport);

  PaperRenderQueueContext context;

  // Configure the render context for a depth/ambient "pass" (this isn't an
  // actual Vulkan pass/subpass), and emit Vulkan commands into the command
  // buffer.
  {
    cmd_buf->PushConstants(PaperShaderPushConstants{
        .light_index = 0,  // ignored
        .eye_index = cam_data.eye_index,
    });

    context.set_draw_mode(PaperRendererDrawMode::kAmbient);

    // Render wireframe.
    cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kWireframe);
    context.set_shader_program(no_lighting_program_);
    render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kWireframe);

    // Render opaque.
    cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kOpaque);
    context.set_shader_program(ambient_light_program_);
    render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kOpaque);
  }

  cmd_buf->SetStencilTest(true);
  cmd_buf->SetDepthTestAndWrite(true, false);
  cmd_buf->SetStencilFrontReference(0xff, 0xff, 0U);
  cmd_buf->SetStencilBackReference(0xff, 0xff, 0U);
  cmd_buf->SetBlendFactors(
      /*src_color_blend=*/vk::BlendFactor::eOne, /*src_alpha_blend=*/vk::BlendFactor::eZero,
      /*dst_color_blend=*/vk::BlendFactor::eOne, /*dst_alpha_blend=*/vk::BlendFactor::eOne);
  cmd_buf->SetBlendOp(vk::BlendOp::eAdd);

  // For each point light, emit Vulkan commands first to draw the stencil shadow
  // geometry for that light, and then to add the lighting contribution for that
  // light.
  const uint32_t num_point_lights = static_cast<uint32_t>(frame_data_->scene->num_point_lights());
  for (uint32_t i = 0; i < num_point_lights; ++i) {
    // Some setup doesn't need to be done for the first light.
    if (i != 0) {
      // Must clear the stencil buffer for every light except the first one.
      cmd_buf->ClearDepthStencilAttachmentRect(cam_data.rect.offset, cam_data.rect.extent,
                                               render_pass_info.clear_depth_stencil,
                                               vk::ImageAspectFlagBits::eStencil);

      // Ensure that each light starts with blending disabled.  Otherwise, the 2nd and subsequent
      // lights would use a different pipeline for |shadow_volume_geometry_program_|.
      cmd_buf->SetBlendEnable(false);

      if (config_.debug) {
        // Replace values set by the debug visualization.
        cmd_buf->SetStencilTest(true);
        cmd_buf->SetWireframe(false);
      }
    }
    cmd_buf->PushConstants(PaperShaderPushConstants{
        .light_index = i,
        .eye_index = cam_data.eye_index,
    });

    // Emit commands for stencil shadow geometry.
    {
      context.set_draw_mode(PaperRendererDrawMode::kShadowVolumeGeometry);
      context.set_shader_program(shadow_volume_geometry_program_);

      // Draw front and back faces of the shadow volumes in a single pass.  We
      // use the standard approach of modifying the stencil buffer only when the
      // depth test is passed, incrementing the stencil value for front-faces
      // and decrementing it for back-faces.
      cmd_buf->SetCullMode(vk::CullModeFlagBits::eNone);
      cmd_buf->SetStencilFrontOps(vk::CompareOp::eAlways, vk::StencilOp::eIncrementAndWrap,
                                  vk::StencilOp::eKeep, vk::StencilOp::eKeep);
      cmd_buf->SetStencilBackOps(vk::CompareOp::eAlways, vk::StencilOp::eDecrementAndWrap,
                                 vk::StencilOp::eKeep, vk::StencilOp::eKeep);

      // Leaving this as eLessOrEqual would result in total self-shadowing by
      // all shadow-casters.
      cmd_buf->SetDepthCompareOp(vk::CompareOp::eLess);

      render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kOpaque);
    }

    // Emit commands for adding lighting contribution.
    {
      context.set_draw_mode(PaperRendererDrawMode::kShadowVolumeLighting);

      // Use a slightly less expensive shader when distance-based attenuation is
      // disabled.
      const bool use_light_falloff = frame_data_->scene->point_lights[i].falloff > 0.f;
      if (use_light_falloff) {
        context.set_shader_program(point_light_falloff_program_);
      } else {
        context.set_shader_program(point_light_program_);
      }

      cmd_buf->SetBlendEnable(true);

      cmd_buf->SetCullMode(vk::CullModeFlagBits::eBack);
      cmd_buf->SetDepthCompareOp(vk::CompareOp::eLessOrEqual);

      cmd_buf->SetStencilFrontOps(vk::CompareOp::eEqual, vk::StencilOp::eKeep, vk::StencilOp::eKeep,
                                  vk::StencilOp::eKeep);
      cmd_buf->SetStencilBackOps(vk::CompareOp::eAlways, vk::StencilOp::eKeep, vk::StencilOp::eKeep,
                                 vk::StencilOp::eKeep);

      render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kOpaque);
    }

    if (config_.debug) {
      if (!escher_->supports_wireframe()) {
        FX_LOGS(WARNING) << "Wireframe not supported; cannot visualize shadow volume geometry.";
      } else {
        context.set_draw_mode(PaperRendererDrawMode::kShadowVolumeGeometry);
        context.set_shader_program(shadow_volume_geometry_debug_program_);

        cmd_buf->SetBlendEnable(false);
        cmd_buf->SetStencilTest(false);
        cmd_buf->SetWireframe(true);
        cmd_buf->SetCullMode(vk::CullModeFlagBits::eNone);

        render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kOpaque);
      }
    }
  }

  // Draw translucent geometry without lighting.
  context.set_draw_mode(PaperRendererDrawMode::kAmbient);
  context.set_shader_program(no_lighting_program_);
  cmd_buf->SetToDefaultState(CommandBuffer::DefaultState::kTranslucent);
  render_queue_.GenerateCommands(cmd_buf, &context, PaperRenderQueueFlagBits::kTranslucent);

  cmd_buf->EndRenderPass();
  frame->AddTimestamp("finished shadow_volume render pass");
}

void PaperRenderer::GenerateDebugCommands(CommandBuffer* cmd_buf) {
  TRACE_DURATION("gfx", "PaperRenderer::GenerateDebugCommands");

  // Exit early if there is no debug rendering to be done.
  if (frame_data_->texts.size() == 0 && frame_data_->lines.size() == 0) {
    return;
  }

  const FramePtr& frame = frame_data_->frame;
  frame->AddTimestamp("started debug render pass");

  auto& output_image = frame_data_->output_image;
  auto swapchain_layout = output_image->swapchain_layout();

  if (swapchain_layout == vk::ImageLayout::eUndefined) {
    FX_LOGS(ERROR) << "PaperRenderer::GenerateDebugCommands(): "
                      "exiting due to undefined swapchain layout.";
    return;
  }

  if (output_image->layout() != swapchain_layout) {
    FX_LOGS(ERROR) << "PaperRenderer::GeneratedDebugCommands(): "
                      "Layout of output_image is not initialized to swapchain layout. Exiting.";
    return;
  }

  cmd_buf->ImageBarrier(
      output_image, swapchain_layout, vk::ImageLayout::eTransferDstOptimal,
      vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer,
      vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eTransferWrite,
      vk::PipelineStageFlagBits::eTransfer, vk::AccessFlagBits::eTransferWrite);

  {
    TRACE_DURATION("gfx", "PaperRenderer::GenerateDebugCommands[text]");
    for (std::size_t i = 0; i < frame_data_->texts.size(); i++) {
      const TextData& td = frame_data_->texts[i];
      debug_font_->Blit(cmd_buf, td.text, output_image, td.offset, td.scale);
    }
  }

  {
    TRACE_DURATION("gfx", "PaperRenderer::GenerateDebugCommands[lines]");
    for (std::size_t i = 0; i < frame_data_->lines.size(); i++) {
      const LineData& ld = frame_data_->lines[i];
      debug_lines_->Blit(cmd_buf, ld.kColor, output_image, ld.rect);
    }
  }

  cmd_buf->ImageBarrier(
      output_image, vk::ImageLayout::eTransferDstOptimal, swapchain_layout,
      vk::PipelineStageFlagBits::eTransfer, vk::AccessFlagBits::eTransferWrite,
      vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eTransfer,
      vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eTransferWrite);

  frame->AddTimestamp("finished debug render pass");
}

// Helper for WarmPipelineAndRenderPassCaches().  Return the render-pass that should be used for
// pipeline creation for the specified config.
static impl::RenderPassPtr WarmRenderPassCache(impl::RenderPassCache* cache,
                                               const PaperRendererConfig& config,
                                               vk::Format output_format,
                                               vk::ImageLayout output_swapchain_layout) {
  TRACE_DURATION("gfx", "PaperRenderer::WarmRenderPassCache", "format",
                 vk::to_string(output_format), "layout", vk::to_string(output_swapchain_layout));
  RenderPassInfo info;

  RenderPassInfo::AttachmentInfo color_attachment_info;
  color_attachment_info.format = output_format;
  color_attachment_info.swapchain_layout = output_swapchain_layout;
  color_attachment_info.sample_count = 1;

  if (!RenderPassInfo::InitRenderPassInfo(&info, color_attachment_info, config.depth_stencil_format,
                                          output_format, config.msaa_sample_count, false)) {
    FX_LOGS(ERROR) << "WarmRenderPassCache(): InitRenderPassInfo failed. Exiting.";
    return nullptr;
  };

  return cache->ObtainRenderPass(info, /*allow_render_pass_creation*/ true);
}

// Helper for WarmPipelineAndRenderPassCaches.
static void BindMeshSpecHelper(CommandBufferPipelineState* cbps, const MeshSpec& mesh_spec) {
  const uint32_t total_attribute_count = mesh_spec.total_attribute_count();
  BlockAllocator allocator(512);
  RenderFuncs::VertexAttributeBinding* attribute_bindings =
      RenderFuncs::NewVertexAttributeBindings(PaperRenderFuncs::kMeshAttributeBindingLocations,
                                              &allocator, mesh_spec, total_attribute_count);

  for (uint32_t i = 0; i < total_attribute_count; ++i) {
    attribute_bindings[i].Bind(cbps);
  }

  // NOTE: we don't actually have a buffer to bind, nor an offset into the bound buffer.  This would
  // be a problem if we tried to generate a draw cmd, but is OK because we just need the stride and
  // input-rate in order to pre-generate pipelines.
  for (uint32_t i = 0; i < VulkanLimits::kNumVertexBuffers; ++i) {
    cbps->BindVertices(i, vk::Buffer(), 0, mesh_spec.stride(i), vk::VertexInputRate::eVertex);
  }
}

// Helper for WarmPipelineAndRenderPassCaches.
static void WarmProgramHelper(impl::PipelineLayoutCache* pipeline_layout_cache,
                              const ShaderProgramPtr& program, CommandBufferPipelineState* cbps,
                              const std::vector<SamplerPtr>& immutable_samplers) {
  TRACE_DURATION("gfx", "PaperRenderer::WarmProgramHelper");

  // Generate pipeline which doesn't require an immutable sampler.
  PipelineLayoutPtr layout = program->ObtainPipelineLayout(pipeline_layout_cache, nullptr);
  cbps->FlushGraphicsPipeline(layout.get(), program.get());

  // Generate pipelines which require immutable samplers.
  for (auto& sampler : immutable_samplers) {
    PipelineLayoutPtr layout = program->ObtainPipelineLayout(pipeline_layout_cache, sampler);
    cbps->FlushGraphicsPipeline(layout.get(), program.get());
  }
}

// Populate caches with all render passes and pipelines required by |config|.
void PaperRenderer::WarmPipelineAndRenderPassCaches(
    Escher* escher, const PaperRendererConfig& config, vk::Format output_format,
    vk::ImageLayout output_swapchain_layout, const std::vector<SamplerPtr>& immutable_samplers) {
  TRACE_DURATION("gfx", "PaperRenderer::WarmPipelineAndRenderPassCaches");

  CommandBufferPipelineState cbps(escher->pipeline_builder()->GetWeakPtr());

  // Obtain and set the render pass; this is the only render pass that is used, so we just need to
  // set it once.
  // TODO(fxbug.dev/44894): try to avoid using this "impl" type directly.
  impl::RenderPassPtr render_pass = WarmRenderPassCache(escher->render_pass_cache(), config,
                                                        output_format, output_swapchain_layout);

  FX_DCHECK(render_pass);
  cbps.set_render_pass(render_pass.get());

  // Set up vertex buffer bindings, as well as bindings to attributes within those buffers.  Of
  // course we don't actually have buffers right now; that's OK... see comments in the helper func
  // for details.
  {
    TRACE_DURATION("gfx", "PaperRenderer::WarmPipelineAndRenderPassCaches[bind mesh spec]");
    BindMeshSpecHelper(&cbps, PaperShapeCache::kShadowVolumeMeshSpec());
  }
  // NOTE: different mesh specs are used depending on whether stencil shadows
  // are enabled.  But it doesn't matter, because CommandBuffer will only use whichever attributes
  // are required for the specified shader.
  // TODO(fxbug.dev/44898): once kShadowVolumeMeshSpec and kStandardMeshSpec are constexpr, we
  // should be able to use static_assert() here.
  FX_DCHECK(PaperShapeCache::kShadowVolumeMeshSpec().attributes[0] ==
            PaperShapeCache::kStandardMeshSpec().attributes[0]);
  FX_DCHECK(PaperShapeCache::kShadowVolumeMeshSpec().attributes[1] ==
            PaperShapeCache::kStandardMeshSpec().attributes[1]);

  switch (config.shadow_type) {
    case PaperRendererShadowType::kNone: {
      if (escher->supports_wireframe()) {
        cbps.SetToDefaultState(CommandBuffer::DefaultState::kWireframe);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kNoLightingProgramData), &cbps, immutable_samplers);
      }

      cbps.SetToDefaultState(CommandBuffer::DefaultState::kOpaque);
      WarmProgramHelper(escher->pipeline_layout_cache(),
                        escher->GetProgram(kAmbientLightProgramData), &cbps, immutable_samplers);

      cbps.SetToDefaultState(CommandBuffer::DefaultState::kTranslucent);
      WarmProgramHelper(escher->pipeline_layout_cache(), escher->GetProgram(kNoLightingProgramData),
                        &cbps, immutable_samplers);
    } break;
    case PaperRendererShadowType::kShadowVolume: {
      // Wireframe shapes (not shadow volumes).
      if (escher->supports_wireframe()) {
        cbps.SetToDefaultState(CommandBuffer::DefaultState::kWireframe);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kNoLightingProgramData), &cbps, immutable_samplers);
      }

      // Ambient opaque.
      {
        cbps.SetToDefaultState(CommandBuffer::DefaultState::kOpaque);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kAmbientLightProgramData), &cbps, immutable_samplers);
      }

      // Set state common to both stencil shadow "geometry" and "lighting" passes.
      cbps.SetToDefaultState(CommandBuffer::DefaultState::kOpaque);
      cbps.SetStencilTest(true);
      cbps.SetDepthTestAndWrite(true, false);
      cbps.SetBlendFactors(
          /*src_color_blend=*/vk::BlendFactor::eOne, /*src_alpha_blend=*/vk::BlendFactor::eZero,
          /*dst_color_blend=*/vk::BlendFactor::eOne, /*dst_alpha_blend=*/vk::BlendFactor::eOne);
      cbps.SetBlendOp(vk::BlendOp::eAdd);

      // Stencil shadow geometry.
      {
        cbps.SetCullMode(vk::CullModeFlagBits::eNone);
        cbps.SetDepthCompareOp(vk::CompareOp::eLess);
        cbps.SetStencilFrontOps(vk::CompareOp::eAlways, vk::StencilOp::eIncrementAndWrap,
                                vk::StencilOp::eKeep, vk::StencilOp::eKeep);
        cbps.SetStencilBackOps(vk::CompareOp::eAlways, vk::StencilOp::eDecrementAndWrap,
                               vk::StencilOp::eKeep, vk::StencilOp::eKeep);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kShadowVolumeGeometryProgramData), &cbps,
                          immutable_samplers);
      }

      // Stencil shadow lighting.
      {
        cbps.SetBlendEnable(true);
        cbps.SetCullMode(vk::CullModeFlagBits::eBack);
        cbps.SetDepthCompareOp(vk::CompareOp::eLessOrEqual);
        cbps.SetStencilFrontOps(vk::CompareOp::eEqual, vk::StencilOp::eKeep, vk::StencilOp::eKeep,
                                vk::StencilOp::eKeep);
        cbps.SetStencilBackOps(vk::CompareOp::eAlways, vk::StencilOp::eKeep, vk::StencilOp::eKeep,
                               vk::StencilOp::eKeep);

        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kPointLightProgramData), &cbps, immutable_samplers);

        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kPointLightFalloffProgramData), &cbps,
                          immutable_samplers);
      }

      // Wireframe shadow volumes (for debug-mode).
      if (escher->supports_wireframe()) {
        cbps.SetBlendEnable(false);
        cbps.SetStencilTest(false);
        cbps.SetWireframe(true);
        cbps.SetCullMode(vk::CullModeFlagBits::eNone);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kShadowVolumeGeometryDebugProgramData), &cbps,
                          immutable_samplers);
      }

      // Translucent.
      {
        cbps.SetToDefaultState(CommandBuffer::DefaultState::kTranslucent);
        WarmProgramHelper(escher->pipeline_layout_cache(),
                          escher->GetProgram(kNoLightingProgramData), &cbps, immutable_samplers);
      }

    } break;
    case PaperRendererShadowType::kEnumCount:
    default:
      FX_CHECK(false) << "unhandled shadow type";
  }
}

}  // namespace escher
