/*
 *
 * 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>
 */

#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 "screenshot_parsing.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"

#ifdef ANDROID

#include <sys/system_properties.h>

#include <android/log.h>

static char android_env[64] = {};
const char *env_var = "debug.vulkan.screenshot";
const char *env_var_old = env_var;
#else  // Linux or Windows
const char *env_var_old = "_VK_SCREENSHOT";
const char *env_var = "VK_SCREENSHOT_FRAMES";
const char *env_var_format = "VK_SCREENSHOT_FORMAT";
#endif

#ifdef ANDROID
char *android_exec(const char *cmd) {
  FILE *pipe = popen(cmd, "r");
  if (pipe != nullptr) {
    fgets(android_env, 64, pipe);
    pclose(pipe);
  }

  // Only if the value is set will we get a string back
  if (strlen(android_env) > 0) {
    __android_log_print(ANDROID_LOG_INFO, "screenshot", "Vulkan screenshot layer capturing: %s",
                        android_env);
    // Do a right strip of " ", "\n", "\r", "\t" for the android_env string
    string android_env_str(android_env);
    android_env_str.erase(android_env_str.find_last_not_of(" \n\r\t") + 1);
    return (char *)android_env_str.c_str();
  }

  return nullptr;
}

char *android_getenv(const char *key) {
  std::string command("getprop ");
  command += key;
  return android_exec(command.c_str());
}

static inline char *local_getenv(const char *name) { return android_getenv(name); }

static inline void local_free_getenv(const char *val) {}

#elif defined(__linux__) || defined(__Fuchsia__)
static inline char *local_getenv(const char *name) { return getenv(name); }

static inline void local_free_getenv(const char *val) {}

#elif defined(_WIN32)

static inline char *local_getenv(const char *name) {
  char *retVal;
  DWORD valSize;

  valSize = GetEnvironmentVariableA(name, NULL, 0);

  // valSize DOES include the null terminator, so for any set variable
  // will always be at least 1. If it's 0, the variable wasn't set.
  if (valSize == 0)
    return NULL;

  // TODO; FIXME This should be using any app defined memory allocation
  retVal = (char *)malloc(valSize);

  GetEnvironmentVariableA(name, retVal, valSize);

  return retVal;
}

static inline void local_free_getenv(const char *val) { free((void *)val); }
#endif

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;
} 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;

// set: list of frames to take screenshots without duplication.
static set<int> screenshotFrames;

// Flag indicating we have received the frame list
static bool screenshotFramesReceived = false;

// Screenshots will be generated from screenShotFrameRange's startFrame to startFrame+count-1 with
// skipped Interval in between.
static FrameRange screenShotFrameRange = {false, 0, SCREEN_SHOT_FRAMES_UNLIMITED,
                                          SCREEN_SHOT_FRAMES_INTERVAL_DEFAULT};

// Get maximum frame number of the frame range
// FrameRange* pFrameRange, the specified frame rang
// return:
//  maximum frame number of the frame range,
//  if it's unlimited range, the return will be SCREEN_SHOT_FRAMES_UNLIMITED
static int getEndFrameOfRange(FrameRange *pFrameRange) {
  int endFrameOfRange = SCREEN_SHOT_FRAMES_UNLIMITED;
  if (pFrameRange->count != SCREEN_SHOT_FRAMES_UNLIMITED) {
    endFrameOfRange = pFrameRange->startFrame + (pFrameRange->count - 1) * pFrameRange->interval;
  }
  return endFrameOfRange;
}

// detect if frameNumber is in the range of pFrameRange, also detect if frameNumber is a frame on
// which a screenshot should be generated. int frameNumber, the frame number. FrameRange*
// pFrameRange, the specified frame range. bool *pScreenShotFrame, if pScreenShotFrame is not
// nullptr, indicate(return) if frameNumber is a frame on which a screenshot should be generated.
// return:
//  if frameNumber is in the range of pFrameRange.
static bool isInScreenShotFrameRange(int frameNumber, FrameRange *pFrameRange,
                                     bool *pScreenShotFrame) {
  bool inRange = false, screenShotFrame = false;
  if (pFrameRange->valid) {
    if (pFrameRange->count != SCREEN_SHOT_FRAMES_UNLIMITED) {
      int endFrame = getEndFrameOfRange(pFrameRange);
      if ((frameNumber >= pFrameRange->startFrame) &&
          ((frameNumber <= endFrame) || (endFrame == SCREEN_SHOT_FRAMES_UNLIMITED))) {
        inRange = true;
      }
    } else {
      inRange = true;
    }
    if (inRange) {
      screenShotFrame = (((frameNumber - pFrameRange->startFrame) % pFrameRange->interval) == 0);
    }
  }
  if (pScreenShotFrame != nullptr) {
    *pScreenShotFrame = screenShotFrame;
  }
  return inRange;
}

// Get users request is specific color space format required
void readScreenShotFormatENV(void) {
#ifndef ANDROID
  vk_screenshot_format = local_getenv(env_var_format);
#endif
  if (vk_screenshot_format && *vk_screenshot_format) {
    if (!strcmp(vk_screenshot_format, "UNORM")) {
      userColorSpaceFormat = UNORM;
    } else if (!strcmp(vk_screenshot_format, "SRGB")) {
      userColorSpaceFormat = SRGB;
    } else if (!strcmp(vk_screenshot_format, "SNORM")) {
      userColorSpaceFormat = SNORM;
    } else if (!strcmp(vk_screenshot_format, "USCALED")) {
      userColorSpaceFormat = USCALED;
    } else if (!strcmp(vk_screenshot_format, "SSCALED")) {
      userColorSpaceFormat = SSCALED;
    } else if (!strcmp(vk_screenshot_format, "UINT")) {
      userColorSpaceFormat = UINT;
    } else if (!strcmp(vk_screenshot_format, "SINT")) {
      userColorSpaceFormat = SINT;
    } else {
#ifdef ANDROID
#else
      fprintf(stderr,
              "Selected format:%s\nIs NOT in the list:\nUNORM, SNORM, USCALED, SSCALED, UINT, "
              "SINT, SRGB\n"
              "Swapchain Colorspace will be used instead\n",
              vk_screenshot_format);
#endif
    }
  }
}

// detect if frameNumber reach or beyond the right edge for screenshot in the range.
// return:
//       if frameNumber is already the last screenshot frame of the range(mean no another screenshot
//       frame number >frameNumber and just in the range) if the range is invalid, return true.
static bool isEndOfScreenShotFrameRange(int frameNumber, FrameRange *pFrameRange) {
  bool endOfScreenShotFrameRange = false, screenShotFrame = false;
  if (!pFrameRange->valid) {
    endOfScreenShotFrameRange = true;
  } else {
    int endFrame = getEndFrameOfRange(pFrameRange);
    if (endFrame != SCREEN_SHOT_FRAMES_UNLIMITED) {
      if (isInScreenShotFrameRange(frameNumber, pFrameRange, &screenShotFrame)) {
        if ((frameNumber >= endFrame) && screenShotFrame) {
          endOfScreenShotFrameRange = true;
        }
      }
    }
  }
  return endOfScreenShotFrameRange;
}

// Parse comma-separated frame list string into the set
static void populate_frame_list(const char *vk_screenshot_frames) {
  string spec(vk_screenshot_frames), word;
  size_t start = 0, comma = 0;

  if (!isOptionBelongToScreenShotRange(vk_screenshot_frames)) {
    while (start < spec.size()) {
      int frameToAdd;
      comma = spec.find(',', start);
      if (comma == string::npos)
        word = string(spec, start);
      else
        word = string(spec, start, comma - start);
      frameToAdd = atoi(word.c_str());
      // Add the frame number to set, but only do it if the word
      // started with a digit and if
      // it's not already in the list
      if (*(word.c_str()) >= '0' && *(word.c_str()) <= '9') {
        screenshotFrames.insert(frameToAdd);
      }
      if (comma == string::npos)
        break;
      start = comma + 1;
    }
  } else {
    int parsingStatus = initScreenShotFrameRange(vk_screenshot_frames, &screenShotFrameRange);
    if (parsingStatus != 0) {
      fprintf(stderr, "Screenshot range error\n");
    }
  }

  screenshotFramesReceived = true;
}

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;
  }
  readScreenShotFormatENV();
}

// 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 writePPM(const char *filename, 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 ((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;
  }

  // Write the data to a PPM file.
  ofstream file(filename, ios::binary);
  assert(file.is_open());

  if (!file.is_open()) {
#ifdef ANDROID
    __android_log_print(
        ANDROID_LOG_DEBUG, "screenshot",
        "Failed to open output file: %s.  Be sure to grant read and write permissions.", filename);
#else
    fprintf(stderr, "Failed to open output file:%s,  Be sure to grant read and write permissions\n",
            filename);
#endif
    return;
  }

  file << "P6\n";
  file << width << "\n";
  file << height << "\n";
  file << 255 << "\n";

  ptr += srLayout.offset;
  if (3 == numChannels) {
    for (uint32_t y = 0; y < height; y++) {
      file.write(ptr, 3 * width);
      ptr += srLayout.rowPitch;
    }
  } else if (4 == numChannels) {
    for (uint32_t y = 0; y < height; y++) {
      const unsigned int *row = (const unsigned int *)ptr;
      for (uint32_t x = 0; x < width; x++) {
        file.write((char *)row, 3);
        row++;
      }
      ptr += srLayout.rowPitch;
    }
  }
  file.close();

  // 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);

  local_free_getenv(vk_screenshot_format);
  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);
  if (screenshotFramesReceived && screenshotFrames.empty() && !screenShotFrameRange.valid) {
    // No screenshots in the list to take
    loader_platform_thread_unlock_mutex(&globalLock);
    return;
  }

  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);
  if (screenshotFramesReceived && screenshotFrames.empty() && !screenShotFrameRange.valid) {
    // No screenshots in the list to take
    loader_platform_thread_unlock_mutex(&globalLock);
    return result;
  }

  // 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);
  if (screenshotFramesReceived && screenshotFrames.empty() && !screenShotFrameRange.valid) {
    // No screenshots in the list to take
    loader_platform_thread_unlock_mutex(&globalLock);
    return;
  }

  // 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 (screenshotFramesReceived && screenshotFrames.empty() && !screenShotFrameRange.valid) {
    // No screenshots in the list to take
    loader_platform_thread_unlock_mutex(&globalLock);
    return result;
  }

  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 (screenshotFramesReceived && screenshotFrames.empty() && !screenShotFrameRange.valid) {
    // No screenshots in the list to take
    loader_platform_thread_unlock_mutex(&globalLock);
    return result;
  }

  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 (!screenshotFramesReceived) {
    const char *vk_screenshot_frames = local_getenv(env_var);
    if (vk_screenshot_frames && *vk_screenshot_frames) {
      populate_frame_list(vk_screenshot_frames);
    }
    // Backwards compatibility
    else {
      const char *_vk_screenshot = local_getenv(env_var_old);
      if (_vk_screenshot && *_vk_screenshot) {
        populate_frame_list(_vk_screenshot);
      }
      local_free_getenv(_vk_screenshot);
    }

    local_free_getenv(vk_screenshot_frames);
  }

  if (result == VK_SUCCESS && (!screenshotFrames.empty() || screenShotFrameRange.valid)) {
    set<int>::iterator it;
    bool inScreenShotFrames = false;
    bool inScreenShotFrameRange = false;
    it = screenshotFrames.find(frameNumber);
    inScreenShotFrames = (it != screenshotFrames.end());
    isInScreenShotFrameRange(frameNumber, &screenShotFrameRange, &inScreenShotFrameRange);
    if ((inScreenShotFrames) || (inScreenShotFrameRange)) {
      string fileName;

#ifdef ANDROID
      // std::to_string is not supported currently
      char buffer[64];
      snprintf(buffer, sizeof(buffer), "/sdcard/Android/%d", frameNumber);
      std::string base(buffer);
      fileName = base + ".ppm";
#else
      fileName = to_string(frameNumber) + ".ppm";
      printf("Screen Capture file is: %s \n", fileName.c_str());
#endif

      VkImage image;
      VkSwapchainKHR swapchain;
      // We'll dump only one image: the first
      swapchain = pPresentInfo->pSwapchains[0];
      image = swapchainMap[swapchain]->imageList[pPresentInfo->pImageIndices[0]];
      writePPM(fileName.c_str(), image);
      if (inScreenShotFrames) {
        screenshotFrames.erase(it);
      }

      if (screenshotFrames.empty() &&
          isEndOfScreenShotFrameRange(frameNumber, &screenShotFrameRange)) {
        // Free all our maps since we are done with them.
        for (auto swapchainIter = swapchainMap.begin(); swapchainIter != swapchainMap.end();
             swapchainIter++) {
          SwapchainMapStruct *swapchainMapElem = swapchainIter->second;
          delete swapchainMapElem;
        }
        for (auto imageIter = imageMap.begin(); imageIter != imageMap.end(); imageIter++) {
          ImageMapStruct *imageMapElem = imageIter->second;
          delete imageMapElem;
        }
        for (auto physDeviceIter = physDeviceMap.begin(); physDeviceIter != physDeviceMap.end();
             physDeviceIter++) {
          PhysDeviceMapStruct *physDeviceMapElem = physDeviceIter->second;
          delete physDeviceMapElem;
        }
        swapchainMap.clear();
        imageMap.clear();
        physDeviceMap.clear();
        screenShotFrameRange.valid = false;
      }
    }
  }
  frameNumber++;
  loader_platform_thread_unlock_mutex(&globalLock);
  return result;
}

// Unused, but this could be provided as an extension or utility to the
// application in the future.
VKAPI_ATTR VkResult VKAPI_CALL SpecifyScreenshotFrames(const char *frameList) {
  populate_frame_list(frameList);
  return VK_SUCCESS;
}

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

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);
}
