// Copyright 2018 The Amber Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/pipeline.h"

#include <algorithm>
#include <cstring>
#include <limits>
#include <set>

#include "src/make_unique.h"
#include "src/type_parser.h"

namespace amber {
namespace {

const char* kDefaultColorBufferFormat = "B8G8R8A8_UNORM";
const char* kDefaultDepthBufferFormat = "D32_SFLOAT_S8_UINT";

// OpenCL coordinates mode is bit 0
const uint32_t kOpenCLNormalizedCoordsBit = 1;
// OpenCL address mode bits are bits 1,2,3.
const uint32_t kOpenCLAddressModeBits = 0xe;
// OpenCL address mode bit values.
const uint32_t kOpenCLAddressModeNone = 0;
const uint32_t kOpenCLAddressModeClampToEdge = 2;
const uint32_t kOpenCLAddressModeClamp = 4;
const uint32_t kOpenCLAddressModeRepeat = 6;
const uint32_t kOpenCLAddressModeMirroredRepeat = 8;
// OpenCL filter mode bits.
const uint32_t kOpenCLFilterModeNearestBit = 0x10;
const uint32_t kOpenCLFilterModeLinearBit = 0x20;

}  // namespace

const char* Pipeline::kGeneratedColorBuffer = "framebuffer";
const char* Pipeline::kGeneratedDepthBuffer = "depth_buffer";
const char* Pipeline::kGeneratedPushConstantBuffer = "push_constant_buffer";

Pipeline::ShaderInfo::ShaderInfo(Shader* shader, ShaderType type)
    : shader_(shader),
      shader_type_(type),
      entry_point_("main"),
      required_subgroup_size_setting_(RequiredSubgroupSizeSetting::kNotSet),
      required_subgroup_size_(0),
      varying_subgroup_size_(false),
      require_full_subgroups_(false),
      emit_debug_info_(false) {}

Pipeline::ShaderInfo::ShaderInfo(const ShaderInfo&) = default;

Pipeline::ShaderInfo::~ShaderInfo() = default;

Pipeline::Pipeline(PipelineType type) : pipeline_type_(type) {}

Pipeline::~Pipeline() = default;

std::unique_ptr<Pipeline> Pipeline::Clone() const {
  auto clone = MakeUnique<Pipeline>(pipeline_type_);
  clone->shaders_ = shaders_;
  clone->color_attachments_ = color_attachments_;
  clone->vertex_buffers_ = vertex_buffers_;
  clone->buffers_ = buffers_;
  clone->depth_stencil_buffer_ = depth_stencil_buffer_;
  clone->index_buffer_ = index_buffer_;
  clone->fb_width_ = fb_width_;
  clone->fb_height_ = fb_height_;
  clone->set_arg_values_ = set_arg_values_;
  clone->pipeline_data_ = pipeline_data_;

  if (!opencl_pod_buffers_.empty()) {
    // Generate specific buffers for the clone.
    clone->GenerateOpenCLPodBuffers();
  }

  return clone;
}

Result Pipeline::AddShader(Shader* shader, ShaderType shader_type) {
  if (!shader)
    return Result("shader can not be null when attached to pipeline");

  if (pipeline_type_ == PipelineType::kCompute &&
      shader_type != kShaderTypeCompute) {
    return Result("only compute shaders allowed in a compute pipeline");
  }
  if (pipeline_type_ == PipelineType::kGraphics &&
      shader_type == kShaderTypeCompute) {
    return Result("can not add a compute shader to a graphics pipeline");
  }

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader)
      return Result("can not add duplicate shader to pipeline");
    if (is->GetType() == shader_type) {
      info.SetShader(shader);
      return {};
    }
  }

  shaders_.emplace_back(shader, shader_type);
  return {};
}

Result Pipeline::SetShaderOptimizations(const Shader* shader,
                                        const std::vector<std::string>& opts) {
  if (!shader)
    return Result("invalid shader specified for optimizations");

  std::set<std::string> seen;
  for (const auto& opt : opts) {
    if (seen.count(opt) != 0)
      return Result("duplicate optimization flag (" + opt + ") set on shader");

    seen.insert(opt);
  }

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader) {
      info.SetShaderOptimizations(opts);
      return {};
    }
  }

  return Result("unknown shader specified for optimizations: " +
                shader->GetName());
}

Result Pipeline::SetShaderCompileOptions(const Shader* shader,
                                         const std::vector<std::string>& opts) {
  if (!shader)
    return Result("invalid shader specified for compile options");

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader) {
      info.SetCompileOptions(opts);
      return {};
    }
  }

  return Result("unknown shader specified for compile options: " +
                shader->GetName());
}

Result Pipeline::SetShaderRequiredSubgroupSize(
    const Shader* shader,
    const ShaderInfo::RequiredSubgroupSizeSetting setting,
    const uint32_t size) {
  if (!shader)
    return Result("invalid shader specified for  required subgroup size");

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader) {
      info.SetRequiredSubgroupSizeSetting(setting, size);
      return {};
    }
  }

  return Result("unknown shader specified for required subgroup size: " +
                shader->GetName());
}

Result Pipeline::SetShaderRequiredSubgroupSize(const Shader* shader,
                                               const uint32_t subgroupSize) {
  const bool isPow2 =
      subgroupSize > 0 && (subgroupSize & (subgroupSize - 1)) == 0;
  if (subgroupSize == 0 || subgroupSize > 128 || !isPow2) {
    return Result("invalid required subgroup size " +
                  std::to_string(subgroupSize) + " specified for shader name " +
                  shader->GetName());
  }
  const ShaderInfo::RequiredSubgroupSizeSetting setting =
      ShaderInfo::RequiredSubgroupSizeSetting::kSetToSpecificSize;
  return SetShaderRequiredSubgroupSize(shader, setting, subgroupSize);
}

Result Pipeline::SetShaderRequiredSubgroupSizeToMinimum(const Shader* shader) {
  const ShaderInfo::RequiredSubgroupSizeSetting subgroupSizeSetting =
      ShaderInfo::RequiredSubgroupSizeSetting::kSetToMinimumSize;
  return SetShaderRequiredSubgroupSize(shader, subgroupSizeSetting, 0);
}

Result Pipeline::SetShaderRequiredSubgroupSizeToMaximum(const Shader* shader) {
  const ShaderInfo::RequiredSubgroupSizeSetting subgroupSizeSetting =
      ShaderInfo::RequiredSubgroupSizeSetting::kSetToMaximumSize;
  return SetShaderRequiredSubgroupSize(shader, subgroupSizeSetting, 0);
}

Result Pipeline::SetShaderVaryingSubgroupSize(const Shader* shader,
                                              const bool isSet) {
  if (!shader)
    return Result("invalid shader specified for varying subgroup size");

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader) {
      info.SetVaryingSubgroupSize(isSet);
      return {};
    }
  }

  return Result("unknown shader specified for varying subgroup size: " +
                shader->GetName());
}

Result Pipeline::SetShaderRequireFullSubgroups(const Shader* shader,
                                               const bool isSet) {
  if (!shader)
    return Result("invalid shader specified for optimizations");

  for (auto& info : shaders_) {
    const auto* is = info.GetShader();
    if (is == shader) {
      info.SetRequireFullSubgroups(isSet);
      return {};
    }
  }

  return Result("unknown shader specified for optimizations: " +
                shader->GetName());
}

Result Pipeline::SetShaderEntryPoint(const Shader* shader,
                                     const std::string& name) {
  if (!shader)
    return Result("invalid shader specified for entry point");
  if (name.empty())
    return Result("entry point should not be blank");

  for (auto& info : shaders_) {
    if (info.GetShader() == shader) {
      if (info.GetEntryPoint() != "main")
        return Result("multiple entry points given for the same shader");

      info.SetEntryPoint(name);
      return {};
    }
  }

  return Result("unknown shader specified for entry point: " +
                shader->GetName());
}

Result Pipeline::SetShaderType(const Shader* shader, ShaderType type) {
  if (!shader)
    return Result("invalid shader specified for shader type");

  for (auto& info : shaders_) {
    if (info.GetShader() == shader) {
      info.SetShaderType(type);
      return {};
    }
  }

  return Result("unknown shader specified for shader type: " +
                shader->GetName());
}

Result Pipeline::Validate() const {
  for (const auto& attachment : color_attachments_) {
    if (attachment.buffer->ElementCount() !=
        (fb_width_ << attachment.base_mip_level) *
            (fb_height_ << attachment.base_mip_level)) {
      return Result(
          "shared framebuffer must have same size over all PIPELINES");
    }
  }

  if (depth_stencil_buffer_.buffer &&
      depth_stencil_buffer_.buffer->ElementCount() != fb_width_ * fb_height_) {
    return Result("shared depth buffer must have same size over all PIPELINES");
  }

  for (auto& buf : GetBuffers()) {
    if (buf.buffer->GetFormat() == nullptr) {
      return Result("buffer (" + std::to_string(buf.descriptor_set) + ":" +
                    std::to_string(buf.binding) + ") requires a format");
    }
  }

  if (pipeline_type_ == PipelineType::kGraphics)
    return ValidateGraphics();

  return ValidateCompute();
}

Result Pipeline::ValidateGraphics() const {
  if (color_attachments_.empty())
    return Result("PIPELINE missing color attachment");

  bool found_vertex = false;
  for (const auto& info : shaders_) {
    const auto* s = info.GetShader();
    if (s->GetType() == kShaderTypeVertex) {
      found_vertex = true;
      break;
    }
  }

  if (!found_vertex)
    return Result("graphics pipeline requires a vertex shader");

  for (const auto& att : color_attachments_) {
    auto width = att.buffer->GetWidth();
    auto height = att.buffer->GetHeight();
    for (uint32_t level = 1; level < att.buffer->GetMipLevels(); level++) {
      width >>= 1;
      if (width == 0)
        return Result("color attachment with " +
                      std::to_string(att.buffer->GetMipLevels()) +
                      " mip levels would have zero width for level " +
                      std::to_string(level));
      height >>= 1;
      if (height == 0)
        return Result("color attachment with " +
                      std::to_string(att.buffer->GetMipLevels()) +
                      " mip levels would have zero height for level " +
                      std::to_string(level));
    }
  }

  return {};
}

Result Pipeline::ValidateCompute() const {
  if (shaders_.empty())
    return Result("compute pipeline requires a compute shader");

  return {};
}

void Pipeline::UpdateFramebufferSizes() {
  uint32_t size = fb_width_ * fb_height_;
  if (size == 0)
    return;

  for (auto& attachment : color_attachments_) {
    auto mip0_width = fb_width_ << attachment.base_mip_level;
    auto mip0_height = fb_height_ << attachment.base_mip_level;
    attachment.buffer->SetWidth(mip0_width);
    attachment.buffer->SetHeight(mip0_height);
    attachment.buffer->SetElementCount(mip0_width * mip0_height);
  }

  if (depth_stencil_buffer_.buffer) {
    depth_stencil_buffer_.buffer->SetWidth(fb_width_);
    depth_stencil_buffer_.buffer->SetHeight(fb_height_);
    depth_stencil_buffer_.buffer->SetElementCount(size);
  }
}

Result Pipeline::AddColorAttachment(Buffer* buf,
                                    uint32_t location,
                                    uint32_t base_mip_level) {
  for (const auto& attachment : color_attachments_) {
    if (attachment.location == location)
      return Result("can not bind two color buffers to the same LOCATION");
    if (attachment.buffer == buf)
      return Result("color buffer may only be bound to a PIPELINE once");
  }

  color_attachments_.push_back(BufferInfo{buf});

  auto& info = color_attachments_.back();
  info.location = location;
  info.type = BufferType::kColor;
  info.base_mip_level = base_mip_level;
  auto mip0_width = fb_width_ << base_mip_level;
  auto mip0_height = fb_height_ << base_mip_level;
  buf->SetWidth(mip0_width);
  buf->SetHeight(mip0_height);
  buf->SetElementCount(mip0_width * mip0_height);

  return {};
}

Result Pipeline::AddResolveTarget(Buffer* buf) {
  resolve_targets_.push_back(BufferInfo{buf});

  auto& info = resolve_targets_.back();
  info.type = BufferType::kResolve;
  buf->SetWidth(fb_width_);
  buf->SetHeight(fb_height_);
  buf->SetElementCount(fb_width_ * fb_height_);

  return {};
}

Result Pipeline::GetLocationForColorAttachment(Buffer* buf,
                                               uint32_t* loc) const {
  for (const auto& info : color_attachments_) {
    if (info.buffer == buf) {
      *loc = info.location;
      return {};
    }
  }
  return Result("Unable to find requested buffer");
}

Result Pipeline::SetDepthStencilBuffer(Buffer* buf) {
  if (depth_stencil_buffer_.buffer != nullptr)
    return Result("can only bind one depth/stencil buffer in a PIPELINE");

  depth_stencil_buffer_.buffer = buf;
  depth_stencil_buffer_.type = BufferType::kDepthStencil;

  buf->SetWidth(fb_width_);
  buf->SetHeight(fb_height_);
  buf->SetElementCount(fb_width_ * fb_height_);
  return {};
}

Result Pipeline::SetIndexBuffer(Buffer* buf) {
  if (index_buffer_ != nullptr)
    return Result("can only bind one INDEX_DATA buffer in a pipeline");

  index_buffer_ = buf;
  return {};
}

Result Pipeline::AddVertexBuffer(Buffer* buf,
                                 uint32_t location,
                                 InputRate rate,
                                 Format* format,
                                 uint32_t offset,
                                 uint32_t stride) {
  for (const auto& vtex : vertex_buffers_) {
    if (vtex.location == location)
      return Result("can not bind two vertex buffers to the same LOCATION");
  }

  vertex_buffers_.push_back(BufferInfo{buf});
  vertex_buffers_.back().location = location;
  vertex_buffers_.back().type = BufferType::kVertex;
  vertex_buffers_.back().input_rate = rate;
  vertex_buffers_.back().format = format;
  vertex_buffers_.back().offset = offset;
  vertex_buffers_.back().stride = stride;
  return {};
}

Result Pipeline::SetPushConstantBuffer(Buffer* buf) {
  if (push_constant_buffer_.buffer != nullptr)
    return Result("can only bind one push constant buffer in a PIPELINE");

  push_constant_buffer_.buffer = buf;
  push_constant_buffer_.type = BufferType::kPushConstant;
  return {};
}

Result Pipeline::CreatePushConstantBuffer() {
  if (push_constant_buffer_.buffer != nullptr)
    return Result("can only bind one push constant buffer in a PIPELINE");

  TypeParser parser;
  auto type = parser.Parse("R8_UINT");
  auto fmt = MakeUnique<Format>(type.get());

  std::unique_ptr<Buffer> buf = MakeUnique<Buffer>();
  buf->SetName(kGeneratedPushConstantBuffer);
  buf->SetFormat(fmt.get());

  push_constant_buffer_.buffer = buf.get();
  push_constant_buffer_.type = BufferType::kPushConstant;

  formats_.push_back(std::move(fmt));
  types_.push_back(std::move(type));
  opencl_push_constants_ = std::move(buf);

  return {};
}

std::unique_ptr<Buffer> Pipeline::GenerateDefaultColorAttachmentBuffer() {
  TypeParser parser;
  auto type = parser.Parse(kDefaultColorBufferFormat);
  auto fmt = MakeUnique<Format>(type.get());

  std::unique_ptr<Buffer> buf = MakeUnique<Buffer>();
  buf->SetName(kGeneratedColorBuffer);
  buf->SetFormat(fmt.get());

  formats_.push_back(std::move(fmt));
  types_.push_back(std::move(type));
  return buf;
}

std::unique_ptr<Buffer>
Pipeline::GenerateDefaultDepthStencilAttachmentBuffer() {
  TypeParser parser;
  auto type = parser.Parse(kDefaultDepthBufferFormat);
  auto fmt = MakeUnique<Format>(type.get());

  std::unique_ptr<Buffer> buf = MakeUnique<Buffer>();
  buf->SetName(kGeneratedDepthBuffer);
  buf->SetFormat(fmt.get());

  formats_.push_back(std::move(fmt));
  types_.push_back(std::move(type));
  return buf;
}

Buffer* Pipeline::GetBufferForBinding(uint32_t descriptor_set,
                                      uint32_t binding) const {
  for (const auto& info : buffers_) {
    if (info.descriptor_set == descriptor_set && info.binding == binding)
      return info.buffer;
  }
  return nullptr;
}

void Pipeline::AddBuffer(Buffer* buf,
                         BufferType type,
                         uint32_t descriptor_set,
                         uint32_t binding,
                         uint32_t base_mip_level,
                         uint32_t dynamic_offset,
                         uint64_t descriptor_offset,
                         uint64_t descriptor_range) {
  buffers_.push_back(BufferInfo{buf});

  auto& info = buffers_.back();
  info.descriptor_set = descriptor_set;
  info.binding = binding;
  info.type = type;
  info.base_mip_level = base_mip_level;
  info.dynamic_offset = dynamic_offset;
  info.sampler = buf->GetSampler();
  info.descriptor_offset = descriptor_offset;
  info.descriptor_range = descriptor_range;
}

void Pipeline::AddBuffer(Buffer* buf,
                         BufferType type,
                         const std::string& arg_name) {
  // If this buffer binding already exists, overwrite with the new buffer.
  for (auto& info : buffers_) {
    if (info.arg_name == arg_name) {
      info.buffer = buf;
      return;
    }
  }

  buffers_.push_back(BufferInfo{buf});

  auto& info = buffers_.back();
  info.type = type;
  info.arg_name = arg_name;
  info.descriptor_set = std::numeric_limits<uint32_t>::max();
  info.binding = std::numeric_limits<uint32_t>::max();
  info.arg_no = std::numeric_limits<uint32_t>::max();
  info.base_mip_level = 0;
  info.dynamic_offset = 0;
}

void Pipeline::AddBuffer(Buffer* buf, BufferType type, uint32_t arg_no) {
  // If this buffer binding already exists, overwrite with the new buffer.
  for (auto& info : buffers_) {
    if (info.arg_no == arg_no) {
      info.buffer = buf;
      return;
    }
  }

  buffers_.push_back(BufferInfo{buf});

  auto& info = buffers_.back();
  info.type = type;
  info.arg_no = arg_no;
  info.descriptor_set = std::numeric_limits<uint32_t>::max();
  info.binding = std::numeric_limits<uint32_t>::max();
  info.base_mip_level = 0;
  info.dynamic_offset = 0;
}

void Pipeline::ClearBuffers(uint32_t descriptor_set, uint32_t binding) {
  buffers_.erase(
      std::remove_if(buffers_.begin(), buffers_.end(),
                     [descriptor_set, binding](BufferInfo& info) -> bool {
                       return (info.descriptor_set == descriptor_set &&
                               info.binding == binding);
                     }),
      buffers_.end());
}

void Pipeline::AddSampler(Sampler* sampler,
                          uint32_t descriptor_set,
                          uint32_t binding) {
  samplers_.push_back(SamplerInfo{sampler});

  auto& info = samplers_.back();
  info.descriptor_set = descriptor_set;
  info.binding = binding;
  info.mask = std::numeric_limits<uint32_t>::max();
}

void Pipeline::AddSampler(Sampler* sampler, const std::string& arg_name) {
  for (auto& info : samplers_) {
    if (info.arg_name == arg_name) {
      info.sampler = sampler;
      return;
    }
  }

  samplers_.push_back(SamplerInfo{sampler});

  auto& info = samplers_.back();
  info.arg_name = arg_name;
  info.descriptor_set = std::numeric_limits<uint32_t>::max();
  info.binding = std::numeric_limits<uint32_t>::max();
  info.arg_no = std::numeric_limits<uint32_t>::max();
  info.mask = std::numeric_limits<uint32_t>::max();
}

void Pipeline::AddSampler(Sampler* sampler, uint32_t arg_no) {
  for (auto& info : samplers_) {
    if (info.arg_no == arg_no) {
      info.sampler = sampler;
      return;
    }
  }

  samplers_.push_back(SamplerInfo{sampler});

  auto& info = samplers_.back();
  info.arg_no = arg_no;
  info.descriptor_set = std::numeric_limits<uint32_t>::max();
  info.binding = std::numeric_limits<uint32_t>::max();
  info.mask = std::numeric_limits<uint32_t>::max();
}

void Pipeline::AddSampler(uint32_t mask,
                          uint32_t descriptor_set,
                          uint32_t binding) {
  samplers_.push_back(SamplerInfo{nullptr});

  auto& info = samplers_.back();
  info.arg_name = "";
  info.arg_no = std::numeric_limits<uint32_t>::max();
  info.mask = mask;
  info.descriptor_set = descriptor_set;
  info.binding = binding;
}

void Pipeline::ClearSamplers(uint32_t descriptor_set, uint32_t binding) {
  samplers_.erase(
      std::remove_if(samplers_.begin(), samplers_.end(),
                     [descriptor_set, binding](SamplerInfo& info) -> bool {
                       return (info.descriptor_set == descriptor_set &&
                               info.binding == binding);
                     }),
      samplers_.end());
}

Result Pipeline::UpdateOpenCLBufferBindings() {
  if (!IsCompute() || GetShaders().empty() ||
      GetShaders()[0].GetShader()->GetFormat() != kShaderFormatOpenCLC) {
    return {};
  }

  const auto& shader_info = GetShaders()[0];
  const auto& descriptor_map = shader_info.GetDescriptorMap();
  if (descriptor_map.empty())
    return {};

  const auto iter = descriptor_map.find(shader_info.GetEntryPoint());
  if (iter == descriptor_map.end())
    return {};

  for (auto& info : samplers_) {
    if (info.descriptor_set == std::numeric_limits<uint32_t>::max() &&
        info.binding == std::numeric_limits<uint32_t>::max()) {
      for (const auto& entry : iter->second) {
        if (entry.arg_name == info.arg_name ||
            entry.arg_ordinal == info.arg_no) {
          if (entry.kind !=
              Pipeline::ShaderInfo::DescriptorMapEntry::Kind::SAMPLER) {
            return Result("Sampler bound to non-sampler kernel arg");
          }
          info.descriptor_set = entry.descriptor_set;
          info.binding = entry.binding;
        }
      }
    }
  }

  for (auto& info : buffers_) {
    if (info.descriptor_set == std::numeric_limits<uint32_t>::max() &&
        info.binding == std::numeric_limits<uint32_t>::max()) {
      for (const auto& entry : iter->second) {
        if (entry.arg_name == info.arg_name ||
            entry.arg_ordinal == info.arg_no) {
          // Buffer storage class consistency checks.
          if (info.type == BufferType::kUnknown) {
            // Set the appropriate buffer type.
            switch (entry.kind) {
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::UBO:
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD_UBO:
                info.type = BufferType::kUniform;
                break;
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::SSBO:
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD:
                info.type = BufferType::kStorage;
                break;
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::RO_IMAGE:
                info.type = BufferType::kSampledImage;
                break;
              case Pipeline::ShaderInfo::DescriptorMapEntry::Kind::WO_IMAGE:
                info.type = BufferType::kStorageImage;
                break;
              default:
                return Result("Unhandled buffer type for OPENCL-C shader");
            }
          } else if (info.type == BufferType::kUniform) {
            if (entry.kind !=
                    Pipeline::ShaderInfo::DescriptorMapEntry::Kind::UBO &&
                entry.kind !=
                    Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD_UBO) {
              return Result("Buffer " + info.buffer->GetName() +
                            " must be a uniform binding");
            }
          } else if (info.type == BufferType::kStorage) {
            if (entry.kind !=
                    Pipeline::ShaderInfo::DescriptorMapEntry::Kind::SSBO &&
                entry.kind !=
                    Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD) {
              return Result("Buffer " + info.buffer->GetName() +
                            " must be a storage binding");
            }
          } else if (info.type == BufferType::kSampledImage) {
            if (entry.kind !=
                Pipeline::ShaderInfo::DescriptorMapEntry::Kind::RO_IMAGE) {
              return Result("Buffer " + info.buffer->GetName() +
                            " must be a read-only image binding");
            }
          } else if (info.type == BufferType::kStorageImage) {
            if (entry.kind !=
                Pipeline::ShaderInfo::DescriptorMapEntry::Kind::WO_IMAGE) {
              return Result("Buffer " + info.buffer->GetName() +
                            " must be a write-only image binding");
            }
          } else {
            return Result("Unhandled buffer type for OPENCL-C shader");
          }
          info.descriptor_set = entry.descriptor_set;
          info.binding = entry.binding;
        }
      }
    }
  }

  return {};
}

Result Pipeline::GenerateOpenCLPodBuffers() {
  if (!IsCompute() || GetShaders().empty() ||
      GetShaders()[0].GetShader()->GetFormat() != kShaderFormatOpenCLC) {
    return {};
  }

  const auto& shader_info = GetShaders()[0];
  const auto& descriptor_map = shader_info.GetDescriptorMap();
  if (descriptor_map.empty())
    return {};

  const auto iter = descriptor_map.find(shader_info.GetEntryPoint());
  if (iter == descriptor_map.end())
    return {};

  // For each SET command, do the following:
  // 1. Find the descriptor map entry for that argument.
  // 2. Find or create the buffer for the descriptor set and binding pair.
  // 3. Write the data for the SET command at the right offset.
  for (const auto& arg_info : SetArgValues()) {
    uint32_t descriptor_set = std::numeric_limits<uint32_t>::max();
    uint32_t binding = std::numeric_limits<uint32_t>::max();
    uint32_t offset = 0;
    uint32_t arg_size = 0;
    bool uses_name = !arg_info.name.empty();
    Pipeline::ShaderInfo::DescriptorMapEntry::Kind kind =
        Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD;
    for (const auto& entry : iter->second) {
      if (entry.kind != Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD &&
          entry.kind !=
              Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD_UBO &&
          entry.kind != Pipeline::ShaderInfo::DescriptorMapEntry::Kind::
                            POD_PUSHCONSTANT) {
        continue;
      }

      // Found the right entry.
      if ((uses_name && entry.arg_name == arg_info.name) ||
          entry.arg_ordinal == arg_info.ordinal) {
        descriptor_set = entry.descriptor_set;
        binding = entry.binding;
        offset = entry.pod_offset;
        arg_size = entry.pod_arg_size;
        kind = entry.kind;
        break;
      }
    }

    Buffer* buffer = nullptr;
    if (kind ==
        Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD_PUSHCONSTANT) {
      if (GetPushConstantBuffer().buffer == nullptr) {
        auto r = CreatePushConstantBuffer();
        if (!r.IsSuccess())
          return r;
      }
      buffer = GetPushConstantBuffer().buffer;
    } else {
      if (descriptor_set == std::numeric_limits<uint32_t>::max() ||
          binding == std::numeric_limits<uint32_t>::max()) {
        std::string message =
            "could not find descriptor map entry for SET command: kernel " +
            shader_info.GetEntryPoint();
        if (uses_name) {
          message += ", name " + arg_info.name;
        } else {
          message += ", number " + std::to_string(arg_info.ordinal);
        }
        return Result(message);
      }

      auto buf_iter = opencl_pod_buffer_map_.lower_bound(
          std::make_pair(descriptor_set, binding));
      if (buf_iter == opencl_pod_buffer_map_.end() ||
          buf_iter->first.first != descriptor_set ||
          buf_iter->first.second != binding) {
        // Ensure no buffer was previously bound for this descriptor set and
        // binding pair.
        for (const auto& buf_info : GetBuffers()) {
          if (buf_info.descriptor_set == descriptor_set &&
              buf_info.binding == binding) {
            return Result("previously bound buffer " +
                          buf_info.buffer->GetName() +
                          " to PoD args at descriptor set " +
                          std::to_string(descriptor_set) + " binding " +
                          std::to_string(binding));
          }
        }

        // Add a new buffer for this descriptor set and binding.
        opencl_pod_buffers_.push_back(MakeUnique<Buffer>());
        buffer = opencl_pod_buffers_.back().get();
        auto buffer_type =
            kind == Pipeline::ShaderInfo::DescriptorMapEntry::Kind::POD
                ? BufferType::kStorage
                : BufferType::kUniform;

        // Use an 8-bit type because all the data in the descriptor map is
        // byte-based and it simplifies the logic for sizing below.
        TypeParser parser;
        auto type = parser.Parse("R8_UINT");
        auto fmt = MakeUnique<Format>(type.get());
        buffer->SetFormat(fmt.get());
        formats_.push_back(std::move(fmt));
        types_.push_back(std::move(type));

        buffer->SetName(GetName() + "_pod_buffer_" +
                        std::to_string(descriptor_set) + "_" +
                        std::to_string(binding));
        opencl_pod_buffer_map_.insert(
            buf_iter,
            std::make_pair(std::make_pair(descriptor_set, binding), buffer));
        AddBuffer(buffer, buffer_type, descriptor_set, binding, 0, 0, 0, ~0ULL);
      } else {
        buffer = buf_iter->second;
      }

      // Resize if necessary.
      if (buffer->ValueCount() < offset + arg_size) {
        buffer->SetSizeInElements(offset + arg_size);
      }

      // Check the data size.
      if (arg_size != arg_info.fmt->SizeInBytes()) {
        std::string message = "SET command uses incorrect data size: kernel " +
                              shader_info.GetEntryPoint();
        if (uses_name) {
          message += ", name " + arg_info.name;
        } else {
          message += ", number " + std::to_string(arg_info.ordinal);
        }
        return Result(message);
      }
    }

    // Convert the argument value into bytes. Currently, only scalar arguments
    // are supported.
    const auto arg_byte_size = arg_info.fmt->SizeInBytes();
    std::vector<Value> data_bytes;
    for (uint32_t i = 0; i < arg_byte_size; ++i) {
      Value v;
      if (arg_info.value.IsFloat()) {
        if (arg_byte_size == sizeof(double)) {
          union {
            uint64_t u;
            double d;
          } u;
          u.d = arg_info.value.AsDouble();
          v.SetIntValue((u.u >> (i * 8)) & 0xff);
        } else {
          union {
            uint32_t u;
            float f;
          } u;
          u.f = arg_info.value.AsFloat();
          v.SetIntValue((u.u >> (i * 8)) & 0xff);
        }
      } else {
        v.SetIntValue((arg_info.value.AsUint64() >> (i * 8)) & 0xff);
      }
      data_bytes.push_back(v);
    }
    Result r = buffer->SetDataWithOffset(data_bytes, offset);
    if (!r.IsSuccess())
      return r;
  }

  return {};
}

Result Pipeline::GenerateOpenCLLiteralSamplers() {
  for (auto& info : samplers_) {
    if (info.sampler || info.mask == std::numeric_limits<uint32_t>::max())
      continue;

    auto literal_sampler = MakeUnique<Sampler>();
    literal_sampler->SetName("literal." + std::to_string(info.descriptor_set) +
                             "." + std::to_string(info.binding));

    // The values for addressing modes, filtering modes and coordinate
    // normalization are all defined in the OpenCL header.

    literal_sampler->SetNormalizedCoords(info.mask &
                                         kOpenCLNormalizedCoordsBit);

    uint32_t addressing_bits = info.mask & kOpenCLAddressModeBits;
    AddressMode addressing_mode = AddressMode::kUnknown;
    if (addressing_bits == kOpenCLAddressModeNone ||
        addressing_bits == kOpenCLAddressModeClampToEdge) {
      // CLK_ADDRESS_NONE
      // CLK_ADDERSS_CLAMP_TO_EDGE
      addressing_mode = AddressMode::kClampToEdge;
    } else if (addressing_bits == kOpenCLAddressModeClamp) {
      // CLK_ADDRESS_CLAMP
      addressing_mode = AddressMode::kClampToBorder;
    } else if (addressing_bits == kOpenCLAddressModeRepeat) {
      // CLK_ADDRESS_REPEAT
      addressing_mode = AddressMode::kRepeat;
    } else if (addressing_bits == kOpenCLAddressModeMirroredRepeat) {
      // CLK_ADDRESS_MIRRORED_REPEAT
      addressing_mode = AddressMode::kMirroredRepeat;
    }
    literal_sampler->SetAddressModeU(addressing_mode);
    literal_sampler->SetAddressModeV(addressing_mode);
    // TODO(alan-baker): If this is used with an arrayed image then W should use
    // kClampToEdge always, but this information is not currently available.
    literal_sampler->SetAddressModeW(addressing_mode);

    // Next bit is filtering mode.
    FilterType filtering_mode = FilterType::kUnknown;
    if (info.mask & kOpenCLFilterModeNearestBit) {
      filtering_mode = FilterType::kNearest;
    } else if (info.mask & kOpenCLFilterModeLinearBit) {
      filtering_mode = FilterType::kLinear;
    }
    literal_sampler->SetMagFilter(filtering_mode);
    literal_sampler->SetMinFilter(filtering_mode);

    // TODO(alan-baker): OpenCL wants the border color to be based on image
    // channel orders which aren't accessible.

    // clspv never generates multiple MIPMAP levels.
    literal_sampler->SetMinLOD(0.0f);
    literal_sampler->SetMaxLOD(0.0f);

    opencl_literal_samplers_.push_back(std::move(literal_sampler));
    info.sampler = opencl_literal_samplers_.back().get();
  }

  return {};
}

Result Pipeline::GenerateOpenCLPushConstants() {
  if (!IsCompute() || GetShaders().empty() ||
      GetShaders()[0].GetShader()->GetFormat() != kShaderFormatOpenCLC) {
    return {};
  }

  const auto& shader_info = GetShaders()[0];
  if (shader_info.GetPushConstants().empty())
    return {};

  Result r = CreatePushConstantBuffer();
  if (!r.IsSuccess())
    return r;

  auto* buf = GetPushConstantBuffer().buffer;
  assert(buf);

  // Determine size and contents of the push constant buffer.
  for (const auto& pc : shader_info.GetPushConstants()) {
    assert(pc.size % sizeof(uint32_t) == 0);
    assert(pc.offset % sizeof(uint32_t) == 0);

    if (buf->GetSizeInBytes() < pc.offset + pc.size)
      buf->SetSizeInBytes(pc.offset + pc.size);

    std::vector<uint32_t> bytes(pc.size / sizeof(uint32_t));
    uint32_t base = 0;
    switch (pc.type) {
      case Pipeline::ShaderInfo::PushConstant::PushConstantType::kDimensions:
        // All compute kernel launches are 3D.
        bytes[base] = 3;
        break;
      case Pipeline::ShaderInfo::PushConstant::PushConstantType::kGlobalOffset:
        // Global offsets are not currently supported.
        bytes[base] = 0;
        bytes[base + 1] = 0;
        bytes[base + 2] = 0;
        break;
      case Pipeline::ShaderInfo::PushConstant::PushConstantType::kRegionOffset:
        // Region offsets are not currently supported.
        bytes[base] = 0;
        bytes[base + 1] = 0;
        bytes[base + 2] = 0;
        break;
    }
    memcpy(buf->ValuePtr()->data() + pc.offset, bytes.data(),
           bytes.size() * sizeof(uint32_t));
  }

  return {};
}

}  // namespace amber
