/*
 * Copyright © 2022 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "util/set.h"
#include "anv_private.h"
#include "vk_common_entrypoints.h"

/**
 * The DOOM 64 rendering corruption is happening because the game always uses
 * ```
 * vkCmdPipelineBarrier(VK_IMAGE_LAYOUT_UNDEFINED ->
 *                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
 * vkCmdCopyBufferToImage(...)
 * vkCmdPipelineBarrier(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ->
 *                      VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
 * ```
 * when it wants to update its texture atlas image.
 *
 * According to spec, transitioning from VK_IMAGE_LAYOUT_UNDEFINED means
 * that the current image content might be discarded, but the game relies
 * on it being fully preserved.
 *
 * This work-around layer implements super-barebone layout tracking: allows
 * the first transition from VK_IMAGE_LAYOUT_UNDEFINED, but replaces
 * oldLayout with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL for each
 * subsequent transition of that image.
 *
 * Gen12+ does not ambiguate CCS data on transition from VK_IMAGE_LAYOUT_UNDEFINED
 * so it preserves all compressed information, and this WA is not needed.
 */

void anv_doom64_CmdPipelineBarrier(
    VkCommandBuffer                             commandBuffer,
    VkPipelineStageFlags                        srcStageMask,
    VkPipelineStageFlags                        dstStageMask,
    VkDependencyFlags                           dependencyFlags,
    uint32_t                                    memoryBarrierCount,
    const VkMemoryBarrier*                      pMemoryBarriers,
    uint32_t                                    bufferMemoryBarrierCount,
    const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
    uint32_t                                    imageMemoryBarrierCount,
    const VkImageMemoryBarrier*                 pImageMemoryBarriers)
{
   ANV_FROM_HANDLE(anv_cmd_buffer, command_buffer, commandBuffer);
   assert(command_buffer && command_buffer->device);

   VkImageMemoryBarrier fixed_barrier;
   struct set * defined_images =
      command_buffer->device->workarounds.doom64_images;

   if (defined_images &&
       imageMemoryBarrierCount == 1 && pImageMemoryBarriers &&
       pImageMemoryBarriers[0].oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
       pImageMemoryBarriers[0].newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
      ANV_FROM_HANDLE(anv_image, image, pImageMemoryBarriers[0].image);

      if (!_mesa_set_search(defined_images, image)) {
         _mesa_set_add(defined_images, image);
      } else {
         memcpy(&fixed_barrier, pImageMemoryBarriers, sizeof(VkImageMemoryBarrier));

         fixed_barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

         pImageMemoryBarriers = (const VkImageMemoryBarrier*) &fixed_barrier;
      }
   }

   vk_common_CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask,
                                dependencyFlags, memoryBarrierCount,
                                pMemoryBarriers, bufferMemoryBarrierCount,
                                pBufferMemoryBarriers,
                                imageMemoryBarrierCount,
                                pImageMemoryBarriers);
}

VkResult anv_doom64_CreateImage(
    VkDevice                                    _device,
    const VkImageCreateInfo*                    pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkImage*                                    pImage)
{
   ANV_FROM_HANDLE(anv_device, device, _device);
   assert(device);

   if (!device->workarounds.doom64_images) {
      device->workarounds.doom64_images = _mesa_pointer_set_create(NULL);

      if (!device->workarounds.doom64_images) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      }
   }

   return anv_CreateImage(_device, pCreateInfo, pAllocator, pImage);
}

void anv_doom64_DestroyImage(
    VkDevice                                    _device,
    VkImage                                     _image,
    const VkAllocationCallbacks*                pAllocator)
{
   ANV_FROM_HANDLE(anv_device, device, _device);
   ANV_FROM_HANDLE(anv_image, image, _image);
   assert(device);

   struct set * defined_images = device->workarounds.doom64_images;

   if (image && defined_images) {
      _mesa_set_remove_key(defined_images, image);

      if (!defined_images->entries) {
         _mesa_set_destroy(defined_images, NULL);
         device->workarounds.doom64_images = NULL;
      }
   }

   anv_DestroyImage(_device, _image, pAllocator);
}
