/*
 *
 * Copyright (C) 2015-2016 Valve Corporation
 * Copyright (C) 2015-2016 LunarG, Inc.
 *
 * 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.
 *
 * Author: Cody Northrop <cody@lunarg.com>
 * Author: David Pinedo <david@lunarg.com>
 * Author: Jon Ashburn <jon@lunarg.com>
 *
 *
 * rfb.cpp is based off of screenshot.cpp from VulkanTools, with some changes to
 * output to an rfb server instead of a file.
 */

#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>

using namespace std;

#include "rfb_server.h"
#include "vk_dispatch_table_helper.h"
#include "vk_layer_config.h"
#include "vk_layer_extension_utils.h"
#include "vk_layer_table.h"
#include "vk_layer_utils.h"

namespace screenshot {

static int globalLockInitialized = 0;
static loader_platform_thread_mutex globalLock;

const char *vk_screenshot_format = nullptr;

bool printFormatWarning = true;

typedef enum colorSpaceFormat {
  UNDEFINED = 0,
  UNORM = 1,
  SNORM = 2,
  USCALED = 3,
  SSCALED = 4,
  UINT = 5,
  SINT = 6,
  SRGB = 7
} colorSpaceFormat;

colorSpaceFormat userColorSpaceFormat = UNDEFINED;

// unordered map: associates a swap chain with a device, image extent, format,
// and list of images
typedef struct {
  VkDevice device;
  VkExtent2D imageExtent;
  VkFormat format;
  VkImage *imageList;
  RFBServer server;
} SwapchainMapStruct;
static unordered_map<VkSwapchainKHR, SwapchainMapStruct *> swapchainMap;

// unordered map: associates an image with a device, image extent, and format
typedef struct {
  VkDevice device;
  VkExtent2D imageExtent;
  VkFormat format;
} ImageMapStruct;
static unordered_map<VkImage, ImageMapStruct *> imageMap;

// unordered map: associates a device with a queue, commandPool, and physical
// device also contains per device info including dispatch table
typedef struct {
  VkLayerDispatchTable *device_dispatch_table;
  bool wsi_enabled;
  VkQueue queue;
  std::list<VkCommandPool> commandPools;
  VkPhysicalDevice physicalDevice;
  PFN_vkSetDeviceLoaderData pfn_dev_init;
} DeviceMapStruct;
static unordered_map<VkDevice, DeviceMapStruct *> deviceMap;

// unordered map: associates a physical device with an instance
typedef struct {
  VkInstance instance;
} PhysDeviceMapStruct;
static unordered_map<VkPhysicalDevice, PhysDeviceMapStruct *> physDeviceMap;

static bool memory_type_from_properties(VkPhysicalDeviceMemoryProperties *memory_properties,
                                        uint32_t typeBits, VkFlags requirements_mask,
                                        uint32_t *typeIndex) {
  // Search memtypes to find first index with those properties
  for (uint32_t i = 0; i < 32; i++) {
    if ((typeBits & 1) == 1) {
      // Type is available, does it match user properties?
      if ((memory_properties->memoryTypes[i].propertyFlags & requirements_mask) ==
          requirements_mask) {
        *typeIndex = i;
        return true;
      }
    }
    typeBits >>= 1;
  }
  // No memory types matched, return failure
  return false;
}

static DeviceMapStruct *get_dev_info(VkDevice dev) {
  auto it = deviceMap.find(dev);
  if (it == deviceMap.end())
    return NULL;
  else
    return it->second;
}

static void init_screenshot() {
  if (!globalLockInitialized) {
    // TODO/TBD: Need to delete this mutex sometime.  How???  One
    // suggestion is to call this during vkCreateInstance(), and then we
    // can clean it up during vkDestroyInstance().  However, that requires
    // that the layer have per-instance locks.  We need to come back and
    // address this soon.
    loader_platform_thread_create_mutex(&globalLock);
    globalLockInitialized = 1;
  }
}

// Track allocated resources in writePPM()
// and clean them up when they go out of scope.
struct WritePPMCleanupData {
  VkDevice device;
  VkLayerDispatchTable *pTableDevice;
  VkImage image2;
  VkImage image3;
  VkDeviceMemory mem2;
  VkDeviceMemory mem3;
  bool mem2mapped;
  bool mem3mapped;
  VkCommandBuffer commandBuffer;
  VkCommandPool commandPool;
  ~WritePPMCleanupData();
};

WritePPMCleanupData::~WritePPMCleanupData() {
  if (mem2mapped)
    pTableDevice->UnmapMemory(device, mem2);
  if (mem2)
    pTableDevice->FreeMemory(device, mem2, NULL);
  if (image2)
    pTableDevice->DestroyImage(device, image2, NULL);

  if (mem3mapped)
    pTableDevice->UnmapMemory(device, mem3);
  if (mem3)
    pTableDevice->FreeMemory(device, mem3, NULL);
  if (image3)
    pTableDevice->DestroyImage(device, image3, NULL);

  if (commandBuffer)
    pTableDevice->FreeCommandBuffers(device, commandPool, 1, &commandBuffer);
}

// Save an image to a PPM image file.
//
// This function issues commands to copy/convert the swapchain image
// from whatever compatible format the swapchain image uses
// to a single format (VK_FORMAT_R8G8B8A8_UNORM) so that the converted
// result can be easily written to a PPM file.
//
// Error handling: If there is a problem, this function should silently
// fail without affecting the Present operation going on in the caller.
// The numerous debug asserts are to catch programming errors and are not
// expected to assert.  Recovery and clean up are implemented for image memory
// allocation failures.
// (TODO) It would be nice to pass any failure info to DebugReport or something.
static void writeScreenshot(SwapchainMapStruct *swapchain, VkImage image1) {
  VkResult err;
  bool pass;

  // Bail immediately if we can't find the image.
  if (imageMap.empty() || imageMap.find(image1) == imageMap.end())
    return;

  // Collect object info from maps.  This info is generally recorded
  // by the other functions hooked in this layer.
  VkDevice device = imageMap[image1]->device;
  VkPhysicalDevice physicalDevice = deviceMap[device]->physicalDevice;
  VkInstance instance = physDeviceMap[physicalDevice]->instance;
  VkQueue queue = deviceMap[device]->queue;
  DeviceMapStruct *devMap = get_dev_info(device);
  if (NULL == devMap) {
    assert(0);
    return;
  }
  VkLayerDispatchTable *pTableDevice = devMap->device_dispatch_table;
  VkLayerDispatchTable *pTableQueue =
      get_dev_info(static_cast<VkDevice>(static_cast<void *>(queue)))->device_dispatch_table;
  VkLayerInstanceDispatchTable *pInstanceTable;
  pInstanceTable = instance_dispatch_table(instance);

  // Gather incoming image info and check image format for compatibility with
  // the target format.
  // This function supports both 24-bit and 32-bit swapchain images.
  uint32_t const width = imageMap[image1]->imageExtent.width;
  uint32_t const height = imageMap[image1]->imageExtent.height;
  VkFormat const format = imageMap[image1]->format;
  uint32_t const numChannels = FormatChannelCount(format);
  if (!swapchain->server.Initialize(width, height, 5900))
    return;

  if ((3 != numChannels) && (4 != numChannels)) {
    assert(0);
    return;
  }

  // Initial dest format is undefined as we will look for one
  VkFormat destformat = VK_FORMAT_UNDEFINED;

  // This variable set by readScreenShotFormatENV func during init
  if (userColorSpaceFormat != UNDEFINED) {
    switch (userColorSpaceFormat) {
      case UNORM:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_UNORM;
        else
          destformat = VK_FORMAT_R8G8B8_UNORM;
        break;
      case SRGB:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_SRGB;
        else
          destformat = VK_FORMAT_R8G8B8_SRGB;
        break;
      case SNORM:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_SNORM;
        else
          destformat = VK_FORMAT_R8G8B8_SNORM;
        break;
      case USCALED:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_USCALED;
        else
          destformat = VK_FORMAT_R8G8B8_USCALED;
        break;
      case SSCALED:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_SSCALED;
        else
          destformat = VK_FORMAT_R8G8B8_SSCALED;
        break;
      case UINT:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_UINT;
        else
          destformat = VK_FORMAT_R8G8B8_UINT;
        break;
      case SINT:
        if (numChannels == 4)
          destformat = VK_FORMAT_R8G8B8A8_SINT;
        else
          destformat = VK_FORMAT_R8G8B8_SINT;
        break;
      default:
        destformat = VK_FORMAT_UNDEFINED;
        break;
    }
  }

  // User did not require sepecific format so we use same colorspace with
  // swapchain format
  if (destformat == VK_FORMAT_UNDEFINED) {
    // Here we reserve swapchain color space only as RGBA swizzle will be later.
    //
    // One Potential optimization here would be: set destination to RGB all the
    // time instead RGBA. PPM does not support Alpha channel, so we can write
    // RGB one row by row but RGBA written one pixel at a time.
    // This requires BLIT operation to get involved but current drivers (mostly)
    // does not support BLIT operations on 3 Channel rendertargets.
    // So format conversion gets costly.
    if (numChannels == 4) {
      if (FormatIsUNorm(format))
        destformat = VK_FORMAT_R8G8B8A8_UNORM;
      else if (FormatIsSRGB(format))
        destformat = VK_FORMAT_R8G8B8A8_SRGB;
      else if (FormatIsSNorm(format))
        destformat = VK_FORMAT_R8G8B8A8_SNORM;
      else if (FormatIsUScaled(format))
        destformat = VK_FORMAT_R8G8B8A8_USCALED;
      else if (FormatIsSScaled(format))
        destformat = VK_FORMAT_R8G8B8A8_SSCALED;
      else if (FormatIsUInt(format))
        destformat = VK_FORMAT_R8G8B8A8_UINT;
      else if (FormatIsSInt(format))
        destformat = VK_FORMAT_R8G8B8A8_SINT;
    } else {  // numChannels 3
      if (FormatIsUNorm(format))
        destformat = VK_FORMAT_R8G8B8_UNORM;
      else if (FormatIsSRGB(format))
        destformat = VK_FORMAT_R8G8B8_SRGB;
      else if (FormatIsSNorm(format))
        destformat = VK_FORMAT_R8G8B8_SNORM;
      else if (FormatIsUScaled(format))
        destformat = VK_FORMAT_R8G8B8_USCALED;
      else if (FormatIsSScaled(format))
        destformat = VK_FORMAT_R8G8B8_SSCALED;
      else if (FormatIsUInt(format))
        destformat = VK_FORMAT_R8G8B8_UINT;
      else if (FormatIsSInt(format))
        destformat = VK_FORMAT_R8G8B8_SINT;
    }
  }

  // Still could not find the right format then we use UNORM
  if (destformat == VK_FORMAT_UNDEFINED) {
#ifdef ANDROID
#else
    if (printFormatWarning) {
      fprintf(
          stderr,
          "Swapchain format is not in the list:\nUNORM, SNORM, USCALED, SSCALED, UINT, SINT, SRGB\n"
          "UNORM colorspace will be used instead\n");
      printFormatWarning = false;
    }
#endif
    if (numChannels == 4)
      destformat = VK_FORMAT_R8G8B8A8_UNORM;
    else
      destformat = VK_FORMAT_R8G8B8_UNORM;
  }

  if ((FormatCompatibilityClass(destformat) != FormatCompatibilityClass(format))) {
    assert(0);
    return;
  }

  // General Approach
  //
  // The idea here is to copy/convert the swapchain image into another image
  // that can be mapped and read by the CPU to produce a PPM file.
  // The image must be untiled and converted to a specific format for easy
  // parsing.  The memory for the final image must be host-visible.
  // Note that in Vulkan, a BLIT operation must be used to perform a format
  // conversion.
  //
  // Devices vary in their ability to blit to/from linear and optimal tiling.
  // So we must query the device properties to get this information.
  //
  // If the device cannot BLIT to a LINEAR image, then the operation must be
  // done in two steps:
  // 1) BLIT the swapchain image (image1) to a temp image (image2) that is
  // created with TILING_OPTIMAL.
  // 2) COPY image2 to another temp image (image3) that is created with
  // TILING_LINEAR.
  // 3) Map image 3 and write the PPM file.
  //
  // If the device can BLIT to a LINEAR image, then:
  // 1) BLIT the swapchain image (image1) to a temp image (image2) that is
  // created with TILING_LINEAR.
  // 2) Map image 2 and write the PPM file.
  //
  // There seems to be no way to tell if the swapchain image (image1) is tiled
  // or not.  We therefore assume that the BLIT operation can always read from
  // both linear and optimal tiled (swapchain) images.
  // There is therefore no point in looking at the BLIT_SRC properties.
  //
  // There is also the optimization where the incoming and target formats are
  // the same.  In this case, just do a COPY.

  VkFormatProperties targetFormatProps;
  pInstanceTable->GetPhysicalDeviceFormatProperties(physicalDevice, destformat, &targetFormatProps);
  bool need2steps = false;
  bool copyOnly = false;
  if (destformat == format) {
    copyOnly = true;
  } else {
    bool const bltLinear =
        targetFormatProps.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT ? true : false;
    bool const bltOptimal =
        targetFormatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT ? true : false;
    if (!bltLinear && !bltOptimal) {
      // Cannot blit to either target tiling type.  It should be pretty
      // unlikely to have a device that cannot blit to either type.
      // But punt by just doing a copy and possibly have the wrong
      // colors.  This should be quite rare.
      copyOnly = true;
    } else if (!bltLinear && bltOptimal) {
      // Cannot blit to a linear target but can blt to optimal, so copy
      // after blit is needed.
      need2steps = true;
    }
    // Else bltLinear is available and only 1 step is needed.
  }

  // Put resources that need to be cleaned up in a struct with a destructor
  // so that things get cleaned up when this function is exited.
  WritePPMCleanupData data = {};
  data.device = device;
  data.pTableDevice = pTableDevice;

  // Set up the image creation info for both the blit and copy images, in case
  // both are needed.
  VkImageCreateInfo imgCreateInfo2 = {
      VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
      NULL,
      0,
      VK_IMAGE_TYPE_2D,
      destformat,
      {width, height, 1},
      1,
      1,
      VK_SAMPLE_COUNT_1_BIT,
      VK_IMAGE_TILING_LINEAR,
      VK_IMAGE_USAGE_TRANSFER_DST_BIT,
      VK_SHARING_MODE_EXCLUSIVE,
      0,
      NULL,
      VK_IMAGE_LAYOUT_UNDEFINED,
  };
  VkImageCreateInfo imgCreateInfo3 = imgCreateInfo2;

  // If we need both images, set up image2 to be read/write and tiled.
  if (need2steps) {
    imgCreateInfo2.tiling = VK_IMAGE_TILING_OPTIMAL;
    imgCreateInfo2.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
  }

  VkMemoryAllocateInfo memAllocInfo = {
      VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL,
      0,  // allocationSize, queried later
      0   // memoryTypeIndex, queried later
  };
  VkMemoryRequirements memRequirements;
  VkPhysicalDeviceMemoryProperties memoryProperties;

  // Create image2 and allocate its memory.  It could be the intermediate or
  // final image.
  err = pTableDevice->CreateImage(device, &imgCreateInfo2, NULL, &data.image2);
  assert(!err);
  if (VK_SUCCESS != err)
    return;
  pTableDevice->GetImageMemoryRequirements(device, data.image2, &memRequirements);
  memAllocInfo.allocationSize = memRequirements.size;
  pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
  pass = memory_type_from_properties(
      &memoryProperties, memRequirements.memoryTypeBits,
      need2steps ? VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT : VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
      &memAllocInfo.memoryTypeIndex);
  assert(pass);
  err = pTableDevice->AllocateMemory(device, &memAllocInfo, NULL, &data.mem2);
  assert(!err);
  if (VK_SUCCESS != err)
    return;
  err = pTableQueue->BindImageMemory(device, data.image2, data.mem2, 0);
  assert(!err);
  if (VK_SUCCESS != err)
    return;

  // Create image3 and allocate its memory, if needed.
  if (need2steps) {
    err = pTableDevice->CreateImage(device, &imgCreateInfo3, NULL, &data.image3);
    assert(!err);
    if (VK_SUCCESS != err)
      return;
    pTableDevice->GetImageMemoryRequirements(device, data.image3, &memRequirements);
    memAllocInfo.allocationSize = memRequirements.size;
    pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
    pass = memory_type_from_properties(&memoryProperties, memRequirements.memoryTypeBits,
                                       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
                                       &memAllocInfo.memoryTypeIndex);
    assert(pass);
    err = pTableDevice->AllocateMemory(device, &memAllocInfo, NULL, &data.mem3);
    assert(!err);
    if (VK_SUCCESS != err)
      return;
    err = pTableQueue->BindImageMemory(device, data.image3, data.mem3, 0);
    assert(!err);
    if (VK_SUCCESS != err)
      return;
  }

  // Set up the command buffer.  We get a command buffer from a pool we saved
  // in a hooked function, which would be the application's pool.
  if (deviceMap[device]->commandPools.empty()) {
    assert(!deviceMap[device]->commandPools.empty());
    return;
  }

  VkCommandPool commandPool = deviceMap[device]->commandPools.front();

  const VkCommandBufferAllocateInfo allocCommandBufferInfo = {
      VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, commandPool,
      VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
  data.commandPool = commandPool;
  err = pTableDevice->AllocateCommandBuffers(device, &allocCommandBufferInfo, &data.commandBuffer);
  assert(!err);
  if (VK_SUCCESS != err)
    return;

  VkDevice cmdBuf = static_cast<VkDevice>(static_cast<void *>(data.commandBuffer));
  deviceMap.emplace(cmdBuf, devMap);
  VkLayerDispatchTable *pTableCommandBuffer;
  pTableCommandBuffer = get_dev_info(cmdBuf)->device_dispatch_table;

  // We have just created a dispatchable object, but the dispatch table has
  // not been placed in the object yet.  When a "normal" application creates
  // a command buffer, the dispatch table is installed by the top-level api
  // binding (trampoline.c). But here, we have to do it ourselves.
  if (!devMap->pfn_dev_init) {
    *((const void **)data.commandBuffer) = *(void **)device;
  } else {
    err = devMap->pfn_dev_init(device, (void *)data.commandBuffer);
    assert(!err);
  }

  const VkCommandBufferBeginInfo commandBufferBeginInfo = {
      VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL,
      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};
  err = pTableCommandBuffer->BeginCommandBuffer(data.commandBuffer, &commandBufferBeginInfo);
  assert(!err);

  // This barrier is used to transition from/to present Layout
  VkImageMemoryBarrier presentMemoryBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                                               NULL,
                                               VK_ACCESS_TRANSFER_WRITE_BIT,
                                               VK_ACCESS_TRANSFER_READ_BIT,
                                               VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
                                               VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
                                               VK_QUEUE_FAMILY_IGNORED,
                                               VK_QUEUE_FAMILY_IGNORED,
                                               image1,
                                               {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};

  // This barrier is used to transition from a newly-created layout to a blt
  // or copy destination layout.
  VkImageMemoryBarrier destMemoryBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                                            NULL,
                                            0,
                                            VK_ACCESS_TRANSFER_WRITE_BIT,
                                            VK_IMAGE_LAYOUT_UNDEFINED,
                                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                            VK_QUEUE_FAMILY_IGNORED,
                                            VK_QUEUE_FAMILY_IGNORED,
                                            data.image2,
                                            {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};

  // This barrier is used to transition a dest layout to general layout.
  VkImageMemoryBarrier generalMemoryBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
                                               NULL,
                                               VK_ACCESS_TRANSFER_WRITE_BIT,
                                               VK_ACCESS_TRANSFER_READ_BIT,
                                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                               VK_IMAGE_LAYOUT_GENERAL,
                                               VK_QUEUE_FAMILY_IGNORED,
                                               VK_QUEUE_FAMILY_IGNORED,
                                               data.image2,
                                               {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};

  VkPipelineStageFlags srcStages = VK_PIPELINE_STAGE_TRANSFER_BIT;
  VkPipelineStageFlags dstStages = VK_PIPELINE_STAGE_TRANSFER_BIT;

  // The source image needs to be transitioned from present to transfer
  // source.
  pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL, 0,
                                          NULL, 1, &presentMemoryBarrier);

  // image2 needs to be transitioned from its undefined state to transfer
  // destination.
  pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL, 0,
                                          NULL, 1, &destMemoryBarrier);

  const VkImageCopy imageCopyRegion = {{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
                                       {0, 0, 0},
                                       {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
                                       {0, 0, 0},
                                       {width, height, 1}};

  if (copyOnly) {
    pTableCommandBuffer->CmdCopyImage(data.commandBuffer, image1,
                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, data.image2,
                                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopyRegion);
  } else {
    VkImageBlit imageBlitRegion = {};
    imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    imageBlitRegion.srcSubresource.baseArrayLayer = 0;
    imageBlitRegion.srcSubresource.layerCount = 1;
    imageBlitRegion.srcSubresource.mipLevel = 0;
    imageBlitRegion.srcOffsets[1].x = width;
    imageBlitRegion.srcOffsets[1].y = height;
    imageBlitRegion.srcOffsets[1].z = 1;
    imageBlitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    imageBlitRegion.dstSubresource.baseArrayLayer = 0;
    imageBlitRegion.dstSubresource.layerCount = 1;
    imageBlitRegion.dstSubresource.mipLevel = 0;
    imageBlitRegion.dstOffsets[1].x = width;
    imageBlitRegion.dstOffsets[1].y = height;
    imageBlitRegion.dstOffsets[1].z = 1;

    pTableCommandBuffer->CmdBlitImage(
        data.commandBuffer, image1, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, data.image2,
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlitRegion, VK_FILTER_NEAREST);
    if (need2steps) {
      // image 3 needs to be transitioned from its undefined state to a
      // transfer destination.
      destMemoryBarrier.image = data.image3;
      pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL,
                                              0, NULL, 1, &destMemoryBarrier);

      // Transition image2 so that it can be read for the upcoming copy to
      // image 3.
      destMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
      destMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
      destMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
      destMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
      destMemoryBarrier.image = data.image2;
      pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL,
                                              0, NULL, 1, &destMemoryBarrier);

      // This step essentially untiles the image.
      pTableCommandBuffer->CmdCopyImage(data.commandBuffer, data.image2,
                                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, data.image3,
                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopyRegion);
      generalMemoryBarrier.image = data.image3;
    }
  }

  // The destination needs to be transitioned from the optimal copy format to
  // the format we can read with the CPU.
  pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL, 0,
                                          NULL, 1, &generalMemoryBarrier);

  // Restore the swap chain image layout to what it was before.
  // This may not be strictly needed, but it is generally good to restore
  // things to original state.
  presentMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
  presentMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
  presentMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
  presentMemoryBarrier.dstAccessMask = 0;
  pTableCommandBuffer->CmdPipelineBarrier(data.commandBuffer, srcStages, dstStages, 0, 0, NULL, 0,
                                          NULL, 1, &presentMemoryBarrier);

  err = pTableCommandBuffer->EndCommandBuffer(data.commandBuffer);
  assert(!err);

  VkFence nullFence = {VK_NULL_HANDLE};
  VkSubmitInfo submitInfo;
  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  submitInfo.pNext = NULL;
  submitInfo.waitSemaphoreCount = 0;
  submitInfo.pWaitSemaphores = NULL;
  submitInfo.pWaitDstStageMask = NULL;
  submitInfo.commandBufferCount = 1;
  submitInfo.pCommandBuffers = &data.commandBuffer;
  submitInfo.signalSemaphoreCount = 0;
  submitInfo.pSignalSemaphores = NULL;

  err = pTableQueue->QueueSubmit(queue, 1, &submitInfo, nullFence);
  assert(!err);

  err = pTableQueue->QueueWaitIdle(queue);
  assert(!err);

  err = pTableDevice->DeviceWaitIdle(device);
  assert(!err);

  // Map the final image so that the CPU can read it.
  const VkImageSubresource sr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0};
  VkSubresourceLayout srLayout;
  const char *ptr;
  if (!need2steps) {
    pTableDevice->GetImageSubresourceLayout(device, data.image2, &sr, &srLayout);
    err = pTableDevice->MapMemory(device, data.mem2, 0, VK_WHOLE_SIZE, 0, (void **)&ptr);
    assert(!err);
    if (VK_SUCCESS != err)
      return;
    data.mem2mapped = true;
  } else {
    pTableDevice->GetImageSubresourceLayout(device, data.image3, &sr, &srLayout);
    err = pTableDevice->MapMemory(device, data.mem3, 0, VK_WHOLE_SIZE, 0, (void **)&ptr);
    assert(!err);
    if (VK_SUCCESS != err)
      return;
    data.mem3mapped = true;
  }

  {
    swapchain->server.WaitForFramebufferUpdate();
    swapchain->server.StartUpdate();
    for (uint32_t y = 0; y < height; y++) {
      const unsigned int *row = (const unsigned int *)ptr;
      const char *row_data = (const char *)row;
      swapchain->server.SendBytes(row_data, width * 4);
      ptr += srLayout.rowPitch;
    }
  }

  // Clean up handled by ~WritePPMCleanupData()
}

VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
                                              const VkAllocationCallbacks *pAllocator,
                                              VkInstance *pInstance) {
  VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);

  assert(chain_info->u.pLayerInfo);
  PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
      chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
  assert(fpGetInstanceProcAddr);
  PFN_vkCreateInstance fpCreateInstance =
      (PFN_vkCreateInstance)fpGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");
  if (fpCreateInstance == NULL) {
    return VK_ERROR_INITIALIZATION_FAILED;
  }

  // Advance the link info for the next element on the chain
  chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;

  VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
  if (result != VK_SUCCESS)
    return result;

  initInstanceTable(*pInstance, fpGetInstanceProcAddr);

  init_screenshot();

  return result;
}

// TODO hook DestroyInstance to cleanup

static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
  uint32_t i;
  DeviceMapStruct *devMap = get_dev_info(device);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
  pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
  pDisp->GetSwapchainImagesKHR =
      (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
  pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
  pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
  devMap->wsi_enabled = false;
  for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
    if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
      devMap->wsi_enabled = true;
  }
}

VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu,
                                            const VkDeviceCreateInfo *pCreateInfo,
                                            const VkAllocationCallbacks *pAllocator,
                                            VkDevice *pDevice) {
  VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);

  assert(chain_info->u.pLayerInfo);
  PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
      chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
  PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
  VkInstance instance = physDeviceMap[gpu]->instance;
  PFN_vkCreateDevice fpCreateDevice =
      (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance, "vkCreateDevice");
  if (fpCreateDevice == NULL) {
    return VK_ERROR_INITIALIZATION_FAILED;
  }

  // Advance the link info for the next element on the chain
  chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;

  VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
  if (result != VK_SUCCESS) {
    return result;
  }

  assert(deviceMap.find(*pDevice) == deviceMap.end());
  DeviceMapStruct *deviceMapElem = new DeviceMapStruct;
  deviceMap[*pDevice] = deviceMapElem;

  // Setup device dispatch table
  deviceMapElem->device_dispatch_table = new VkLayerDispatchTable;
  layer_init_device_dispatch_table(*pDevice, deviceMapElem->device_dispatch_table,
                                   fpGetDeviceProcAddr);

  createDeviceRegisterExtensions(pCreateInfo, *pDevice);
  // Create a mapping from a device to a physicalDevice
  deviceMapElem->physicalDevice = gpu;

  // store the loader callback for initializing created dispatchable objects
  chain_info = get_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK);
  if (chain_info) {
    deviceMapElem->pfn_dev_init = chain_info->u.pfnSetDeviceLoaderData;
  } else {
    deviceMapElem->pfn_dev_init = NULL;
  }
  return result;
}

VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance,
                                                        uint32_t *pPhysicalDeviceCount,
                                                        VkPhysicalDevice *pPhysicalDevices) {
  VkResult result;

  VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(instance);
  result = pTable->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
  if (result == VK_SUCCESS && *pPhysicalDeviceCount > 0 && pPhysicalDevices) {
    for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
      // Create a mapping from a physicalDevice to an instance
      if (physDeviceMap[pPhysicalDevices[i]] == NULL) {
        PhysDeviceMapStruct *physDeviceMapElem = new PhysDeviceMapStruct;
        physDeviceMap[pPhysicalDevices[i]] = physDeviceMapElem;
      }
      physDeviceMap[pPhysicalDevices[i]]->instance = instance;
    }
  }
  return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  pDisp->DestroyDevice(device, pAllocator);

  loader_platform_thread_lock_mutex(&globalLock);
  delete pDisp;
  delete devMap;

  deviceMap.erase(device);
  loader_platform_thread_unlock_mutex(&globalLock);
}

VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueNodeIndex,
                                          uint32_t queueIndex, VkQueue *pQueue) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  pDisp->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);

  // Save the device queue in a map if we are taking screenshots.
  loader_platform_thread_lock_mutex(&globalLock);

  VkDevice que = static_cast<VkDevice>(static_cast<void *>(*pQueue));
  deviceMap.emplace(que, devMap);

  // Create a mapping from a device to a queue
  devMap->queue = *pQueue;
  loader_platform_thread_unlock_mutex(&globalLock);
}

VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device,
                                                 const VkCommandPoolCreateInfo *pCreateInfo,
                                                 const VkAllocationCallbacks *pAllocator,
                                                 VkCommandPool *pCommandPool) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  VkResult result = pDisp->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);

  // Save the command pool on a map if we are taking screenshots.
  loader_platform_thread_lock_mutex(&globalLock);

  // Create a mapping from a device to a commandPool
  devMap->commandPools.push_front(*pCommandPool);
  loader_platform_thread_unlock_mutex(&globalLock);
  return result;
}

VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool,
                                              const VkAllocationCallbacks *pAllocator) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  pDisp->DestroyCommandPool(device, commandPool, pAllocator);

  // Remove the command pool from the map if we are taking screenshots.
  loader_platform_thread_lock_mutex(&globalLock);
  // Remove the commandPool from the device mapping
  devMap->commandPools.remove(commandPool);
  loader_platform_thread_unlock_mutex(&globalLock);
  return;
}

VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device,
                                                  const VkSwapchainCreateInfoKHR *pCreateInfo,
                                                  const VkAllocationCallbacks *pAllocator,
                                                  VkSwapchainKHR *pSwapchain) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;

  // This layer does an image copy later on, and the copy command expects the
  // transfer src bit to be on.
  VkSwapchainCreateInfoKHR myCreateInfo = *pCreateInfo;
  myCreateInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
  VkResult result = pDisp->CreateSwapchainKHR(device, &myCreateInfo, pAllocator, pSwapchain);

  // Save the swapchain in a map of we are taking screenshots.
  loader_platform_thread_lock_mutex(&globalLock);

  if (result == VK_SUCCESS) {
    // Create a mapping for a swapchain to a device, image extent, and
    // format
    SwapchainMapStruct *swapchainMapElem = new SwapchainMapStruct;
    swapchainMapElem->device = device;
    swapchainMapElem->imageExtent = pCreateInfo->imageExtent;
    swapchainMapElem->format = pCreateInfo->imageFormat;
    swapchainMap.insert(make_pair(*pSwapchain, swapchainMapElem));

    // Create a mapping for the swapchain object into the dispatch table
    // TODO is this needed? screenshot_device_table_map.emplace((void
    // *)pSwapchain, pTable);
  }
  loader_platform_thread_unlock_mutex(&globalLock);

  return result;
}

VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
                                                     uint32_t *pCount, VkImage *pSwapchainImages) {
  DeviceMapStruct *devMap = get_dev_info(device);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  VkResult result = pDisp->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);

  // Save the swapchain images in a map if we are taking screenshots
  loader_platform_thread_lock_mutex(&globalLock);

  if (result == VK_SUCCESS && pSwapchainImages && !swapchainMap.empty() &&
      swapchainMap.find(swapchain) != swapchainMap.end()) {
    unsigned i;

    for (i = 0; i < *pCount; i++) {
      // Create a mapping for an image to a device, image extent, and
      // format
      if (imageMap[pSwapchainImages[i]] == NULL) {
        ImageMapStruct *imageMapElem = new ImageMapStruct;
        imageMap[pSwapchainImages[i]] = imageMapElem;
      }
      imageMap[pSwapchainImages[i]]->device = swapchainMap[swapchain]->device;
      imageMap[pSwapchainImages[i]]->imageExtent = swapchainMap[swapchain]->imageExtent;
      imageMap[pSwapchainImages[i]]->format = swapchainMap[swapchain]->format;
    }

    // Add list of images to swapchain to image map
    SwapchainMapStruct *swapchainMapElem = swapchainMap[swapchain];
    if (i >= 1 && swapchainMapElem) {
      VkImage *imageList = new VkImage[i];
      swapchainMapElem->imageList = imageList;
      for (unsigned j = 0; j < i; j++) {
        swapchainMapElem->imageList[j] = pSwapchainImages[j];
      }
    }
  }
  loader_platform_thread_unlock_mutex(&globalLock);
  return result;
}

VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue,
                                               const VkPresentInfoKHR *pPresentInfo) {
  static int frameNumber = 0;
  if (frameNumber == 10) {
    fflush(stdout); /* *((int*)0)=0; */
  }
  DeviceMapStruct *devMap = get_dev_info((VkDevice)queue);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;
  VkResult result = pDisp->QueuePresentKHR(queue, pPresentInfo);
  loader_platform_thread_lock_mutex(&globalLock);

  if (result == VK_SUCCESS) {
    VkImage image;
    VkSwapchainKHR swapchain;
    // We'll dump only one image: the first
    swapchain = pPresentInfo->pSwapchains[0];
    image = swapchainMap[swapchain]->imageList[pPresentInfo->pImageIndices[0]];
    writeScreenshot(swapchainMap[swapchain], image);
  }
  frameNumber++;
  loader_platform_thread_unlock_mutex(&globalLock);
  return result;
}

static const VkLayerProperties global_layer = {
    "VK_LAYER_GOOGLE_rfb",
    VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION),
    1,
    "Layer: rfb",
};

VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount,
                                                                VkLayerProperties *pProperties) {
  return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
                                                              uint32_t *pCount,
                                                              VkLayerProperties *pProperties) {
  return util_GetLayerProperties(1, &global_layer, pCount, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(
    const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
  if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
    return util_GetExtensionProperties(0, NULL, pCount, pProperties);

  return VK_ERROR_LAYER_NOT_PRESENT;
}

VKAPI_ATTR VkResult VKAPI_CALL
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
                                   uint32_t *pCount, VkExtensionProperties *pProperties) {
  if (pLayerName && !strcmp(pLayerName, global_layer.layerName))
    return util_GetExtensionProperties(0, NULL, pCount, pProperties);

  assert(physicalDevice);

  VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(physicalDevice);
  return pTable->EnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pCount,
                                                    pProperties);
}

static PFN_vkVoidFunction intercept_core_instance_command(const char *name);

static PFN_vkVoidFunction intercept_core_device_command(const char *name);

static PFN_vkVoidFunction intercept_khr_swapchain_command(const char *name, VkDevice dev);

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char *funcName) {
  PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
  if (proc)
    return proc;

  if (dev == NULL) {
    return NULL;
  }

  proc = intercept_khr_swapchain_command(funcName, dev);
  if (proc)
    return proc;

  DeviceMapStruct *devMap = get_dev_info(dev);
  assert(devMap);
  VkLayerDispatchTable *pDisp = devMap->device_dispatch_table;

  if (pDisp->GetDeviceProcAddr == NULL)
    return NULL;
  return pDisp->GetDeviceProcAddr(dev, funcName);
}

VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance,
                                                             const char *funcName) {
  PFN_vkVoidFunction proc = intercept_core_instance_command(funcName);
  if (proc)
    return proc;

  assert(instance);

  proc = intercept_core_device_command(funcName);
  if (!proc)
    proc = intercept_khr_swapchain_command(funcName, VK_NULL_HANDLE);
  if (proc)
    return proc;

  VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(instance);
  if (pTable->GetInstanceProcAddr == NULL)
    return NULL;
  return pTable->GetInstanceProcAddr(instance, funcName);
}

static PFN_vkVoidFunction intercept_core_instance_command(const char *name) {
  static const struct {
    const char *name;
    PFN_vkVoidFunction proc;
  } core_instance_commands[] = {
      {"vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr)},
      {"vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(CreateInstance)},
      {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(CreateDevice)},
      {"vkEnumeratePhysicalDevices",
       reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices)},
      {"vkEnumerateInstanceLayerProperties",
       reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties)},
      {"vkEnumerateDeviceLayerProperties",
       reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties)},
      {"vkEnumerateInstanceExtensionProperties",
       reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties)},
      {"vkEnumerateDeviceExtensionProperties",
       reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties)}};

  for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
    if (!strcmp(core_instance_commands[i].name, name))
      return core_instance_commands[i].proc;
  }

  return nullptr;
}

static PFN_vkVoidFunction intercept_core_device_command(const char *name) {
  static const struct {
    const char *name;
    PFN_vkVoidFunction proc;
  } core_device_commands[] = {
      {"vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr)},
      {"vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue)},
      {"vkCreateCommandPool", reinterpret_cast<PFN_vkVoidFunction>(CreateCommandPool)},
      {"vkDestroyCommandPool", reinterpret_cast<PFN_vkVoidFunction>(DestroyCommandPool)},
      {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice)},
  };

  for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
    if (!strcmp(core_device_commands[i].name, name))
      return core_device_commands[i].proc;
  }

  return nullptr;
}

static PFN_vkVoidFunction intercept_khr_swapchain_command(const char *name, VkDevice dev) {
  static const struct {
    const char *name;
    PFN_vkVoidFunction proc;
  } khr_swapchain_commands[] = {
      {"vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR)},
      {"vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR)},
      {"vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR)},
  };

  if (dev) {
    DeviceMapStruct *devMap = get_dev_info(dev);
    if (!devMap->wsi_enabled)
      return nullptr;
  }

  for (size_t i = 0; i < ARRAY_SIZE(khr_swapchain_commands); i++) {
    if (!strcmp(khr_swapchain_commands[i].name, name))
      return khr_swapchain_commands[i].proc;
  }

  return nullptr;
}

}  // namespace screenshot

// loader-layer interface v0, just wrappers since there is only a layer

VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
  return screenshot::EnumerateInstanceLayerProperties(pCount, pProperties);
}

VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
    VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties *pProperties) {
  // the layer command handles VK_NULL_HANDLE just fine internally
  assert(physicalDevice == VK_NULL_HANDLE);
  return screenshot::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
}

VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
    const char *pLayerName, uint32_t *pCount, VkExtensionProperties *pProperties) {
  return screenshot::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
}

VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
                                     uint32_t *pCount, VkExtensionProperties *pProperties) {
  // the layer command handles VK_NULL_HANDLE just fine internally
  assert(physicalDevice == VK_NULL_HANDLE);
  return screenshot::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount,
                                                        pProperties);
}

VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev,
                                                                             const char *funcName) {
  return screenshot::GetDeviceProcAddr(dev, funcName);
}

VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
  return screenshot::GetInstanceProcAddr(instance, funcName);
}
