/*
 * Copyright © 2024 Collabora, Ltd.
 *
 * 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 "vk_shader.h"

#include "vk_alloc.h"
#include "vk_command_buffer.h"
#include "vk_common_entrypoints.h"
#include "vk_descriptor_set_layout.h"
#include "vk_device.h"
#include "vk_nir.h"
#include "vk_physical_device.h"
#include "vk_physical_device_features.h"
#include "vk_pipeline.h"

#include "util/mesa-sha1.h"

#include "nir.h"

static void
vk_shader_init(struct vk_shader *shader,
               struct vk_device *device,
               const struct vk_shader_ops *ops,
               gl_shader_stage stage)
{
   vk_object_base_init(device, &shader->base, VK_OBJECT_TYPE_SHADER_EXT);
   shader->ops = ops;
   shader->stage = stage;
}

void *
vk_shader_zalloc(struct vk_device *device,
                 const struct vk_shader_ops *ops,
                 gl_shader_stage stage,
                 const VkAllocationCallbacks *alloc,
                 size_t size)
{
   /* For internal allocations, we need to allocate from the device scope
    * because they might be put in pipeline caches.  Importantly, it is
    * impossible for the client to get at this pointer and we apply this
    * heuristic before we account for allocation fallbacks so this will only
    * ever happen for internal shader objectx.
    */
   const VkSystemAllocationScope alloc_scope =
      alloc == &device->alloc ? VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
                              : VK_SYSTEM_ALLOCATION_SCOPE_OBJECT;

   struct vk_shader *shader = vk_zalloc2(&device->alloc, alloc, size, 8,
                                         alloc_scope);
   if (shader == NULL)
      return NULL;

   vk_shader_init(shader, device, ops, stage);

   return shader;
}

void *
vk_shader_multizalloc(struct vk_device *device,
                      struct vk_multialloc *ma,
                      const struct vk_shader_ops *ops,
                      gl_shader_stage stage,
                      const VkAllocationCallbacks *alloc)
{
   struct vk_shader *shader =
      vk_multialloc_zalloc2(ma, &device->alloc, alloc,
                            VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
   if (!shader)
      return NULL;

   vk_shader_init(shader, device, ops, stage);

   return shader;
}

void
vk_shader_free(struct vk_device *device,
               const VkAllocationCallbacks *alloc,
               struct vk_shader *shader)
{
   vk_object_base_finish(&shader->base);
   vk_free2(&device->alloc, alloc, shader);
}

int
vk_shader_cmp_graphics_stages(gl_shader_stage a, gl_shader_stage b)
{
   static const int stage_order[MESA_SHADER_MESH + 1] = {
      [MESA_SHADER_VERTEX] = 1,
      [MESA_SHADER_TESS_CTRL] = 2,
      [MESA_SHADER_TESS_EVAL] = 3,
      [MESA_SHADER_GEOMETRY] = 4,
      [MESA_SHADER_TASK] = 5,
      [MESA_SHADER_MESH] = 6,
      [MESA_SHADER_FRAGMENT] = 7,
   };

   assert(a < ARRAY_SIZE(stage_order) && stage_order[a] > 0);
   assert(b < ARRAY_SIZE(stage_order) && stage_order[b] > 0);

   return stage_order[a] - stage_order[b];
}

struct stage_idx {
   gl_shader_stage stage;
   uint32_t idx;
};

static int
cmp_stage_idx(const void *_a, const void *_b)
{
   const struct stage_idx *a = _a, *b = _b;
   return vk_shader_cmp_graphics_stages(a->stage, b->stage);
}

static nir_shader *
vk_shader_to_nir(struct vk_device *device,
                 const VkShaderCreateInfoEXT *info,
                 const struct vk_pipeline_robustness_state *rs)
{
   const struct vk_device_shader_ops *ops = device->shader_ops;

   const gl_shader_stage stage = vk_to_mesa_shader_stage(info->stage);
   const nir_shader_compiler_options *nir_options =
      ops->get_nir_options(device->physical, stage, rs);
   struct spirv_to_nir_options spirv_options =
      ops->get_spirv_options(device->physical, stage, rs);

   enum gl_subgroup_size subgroup_size = vk_get_subgroup_size(
      vk_spirv_version(info->pCode, info->codeSize),
      stage, info->pNext,
      info->flags & VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT,
      info->flags &VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);

   nir_shader *nir = vk_spirv_to_nir(device,
                                     info->pCode, info->codeSize,
                                     stage, info->pName,
                                     subgroup_size,
                                     info->pSpecializationInfo,
                                     &spirv_options, nir_options,
                                     false /* internal */, NULL);
   if (nir == NULL)
      return NULL;

   if (ops->preprocess_nir != NULL)
      ops->preprocess_nir(device->physical, nir, rs);

   return nir;
}

struct set_layouts {
   struct vk_descriptor_set_layout *set_layouts[MESA_VK_MAX_DESCRIPTOR_SETS];
};

static void
vk_shader_compile_info_init(struct vk_shader_compile_info *info,
                            struct set_layouts *set_layouts,
                            const VkShaderCreateInfoEXT *vk_info,
                            const struct vk_pipeline_robustness_state *rs,
                            nir_shader *nir)
{
   for (uint32_t sl = 0; sl < vk_info->setLayoutCount; sl++) {
      set_layouts->set_layouts[sl] =
         vk_descriptor_set_layout_from_handle(vk_info->pSetLayouts[sl]);
   }

   *info = (struct vk_shader_compile_info) {
      .stage = nir->info.stage,
      .flags = vk_info->flags,
      .next_stage_mask = vk_info->nextStage,
      .nir = nir,
      .robustness = rs,
      .set_layout_count = vk_info->setLayoutCount,
      .set_layouts = set_layouts->set_layouts,
      .push_constant_range_count = vk_info->pushConstantRangeCount,
      .push_constant_ranges = vk_info->pPushConstantRanges,
   };
}

PRAGMA_DIAGNOSTIC_PUSH
PRAGMA_DIAGNOSTIC_ERROR(-Wpadded)
struct vk_shader_bin_header {
   char mesavkshaderbin[16];
   VkDriverId driver_id;
   uint8_t uuid[VK_UUID_SIZE];
   uint32_t version;
   uint64_t size;
   uint8_t sha1[SHA1_DIGEST_LENGTH];
   uint32_t _pad;
};
PRAGMA_DIAGNOSTIC_POP
static_assert(sizeof(struct vk_shader_bin_header) == 72,
              "This struct has no holes");

static void
vk_shader_bin_header_init(struct vk_shader_bin_header *header,
                          struct vk_physical_device *device)
{
   *header = (struct vk_shader_bin_header) {
      .mesavkshaderbin = "MesaVkShaderBin",
      .driver_id = device->properties.driverID,
   };

   memcpy(header->uuid, device->properties.shaderBinaryUUID, VK_UUID_SIZE);
   header->version = device->properties.shaderBinaryVersion;
}

static VkResult
vk_shader_serialize(struct vk_device *device,
                    struct vk_shader *shader,
                    struct blob *blob)
{
   struct vk_shader_bin_header header;
   vk_shader_bin_header_init(&header, device->physical);

   ASSERTED intptr_t header_offset = blob_reserve_bytes(blob, sizeof(header));
   assert(header_offset == 0);

   bool success = shader->ops->serialize(device, shader, blob);
   if (!success || blob->out_of_memory)
      return VK_INCOMPLETE;

   /* Finalize and write the header */
   header.size = blob->size;
   if (blob->data != NULL) {
      assert(sizeof(header) <= blob->size);

      struct mesa_sha1 sha1_ctx;
      _mesa_sha1_init(&sha1_ctx);

      /* Hash the header with a zero SHA1 */
      _mesa_sha1_update(&sha1_ctx, &header, sizeof(header));

      /* Hash the serialized data */
      _mesa_sha1_update(&sha1_ctx, blob->data + sizeof(header),
                        blob->size - sizeof(header));

      _mesa_sha1_final(&sha1_ctx, header.sha1);

      blob_overwrite_bytes(blob, header_offset, &header, sizeof(header));
   }

   return VK_SUCCESS;
}

static VkResult
vk_shader_deserialize(struct vk_device *device,
                      size_t data_size, const void *data,
                      const VkAllocationCallbacks* pAllocator,
                      struct vk_shader **shader_out)
{
   const struct vk_device_shader_ops *ops = device->shader_ops;

   struct blob_reader blob;
   blob_reader_init(&blob, data, data_size);

   struct vk_shader_bin_header header, ref_header;
   blob_copy_bytes(&blob, &header, sizeof(header));
   if (blob.overrun)
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   vk_shader_bin_header_init(&ref_header, device->physical);

   if (memcmp(header.mesavkshaderbin, ref_header.mesavkshaderbin,
              sizeof(header.mesavkshaderbin)))
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   if (header.driver_id != ref_header.driver_id)
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   if (memcmp(header.uuid, ref_header.uuid, sizeof(header.uuid)))
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   /* From the Vulkan 1.3.276 spec:
    *
    *    "Guaranteed compatibility of shader binaries is expressed through a
    *    combination of the shaderBinaryUUID and shaderBinaryVersion members
    *    of the VkPhysicalDeviceShaderObjectPropertiesEXT structure queried
    *    from a physical device. Binary shaders retrieved from a physical
    *    device with a certain shaderBinaryUUID are guaranteed to be
    *    compatible with all other physical devices reporting the same
    *    shaderBinaryUUID and the same or higher shaderBinaryVersion."
    *
    * We handle the version check here on behalf of the driver and then pass
    * the version into the driver's deserialize callback.
    *
    * If a driver doesn't want to mess with versions, they can always make the
    * UUID a hash and always report version 0 and that will make this check
    * effectively a no-op.
    */
   if (header.version > ref_header.version)
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   /* Reject shader binaries that are the wrong size. */
   if (header.size != data_size)
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   assert(blob.current == (uint8_t *)data + sizeof(header));
   blob.end = (uint8_t *)data + data_size;

   struct mesa_sha1 sha1_ctx;
   _mesa_sha1_init(&sha1_ctx);

   /* Hash the header with a zero SHA1 */
   struct vk_shader_bin_header sha1_header = header;
   memset(sha1_header.sha1, 0, sizeof(sha1_header.sha1));
   _mesa_sha1_update(&sha1_ctx, &sha1_header, sizeof(sha1_header));

   /* Hash the serialized data */
   _mesa_sha1_update(&sha1_ctx, (uint8_t *)data + sizeof(header),
                     data_size - sizeof(header));

   _mesa_sha1_final(&sha1_ctx, ref_header.sha1);
   if (memcmp(header.sha1, ref_header.sha1, sizeof(header.sha1)))
      return vk_error(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT);

   /* We've now verified that the header matches and that the data has the
    * right SHA1 hash so it's safe to call into the driver.
    */
   return ops->deserialize(device, &blob, header.version,
                           pAllocator, shader_out);
}

VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetShaderBinaryDataEXT(VkDevice _device,
                                 VkShaderEXT _shader,
                                 size_t *pDataSize,
                                 void *pData)
{
   VK_FROM_HANDLE(vk_device, device, _device);
   VK_FROM_HANDLE(vk_shader, shader, _shader);
   VkResult result;

   /* From the Vulkan 1.3.275 spec:
    *
    *    "If pData is NULL, then the size of the binary shader code of the
    *    shader object, in bytes, is returned in pDataSize. Otherwise,
    *    pDataSize must point to a variable set by the user to the size of the
    *    buffer, in bytes, pointed to by pData, and on return the variable is
    *    overwritten with the amount of data actually written to pData. If
    *    pDataSize is less than the size of the binary shader code, nothing is
    *    written to pData, and VK_INCOMPLETE will be returned instead of
    *    VK_SUCCESS."
    *
    * This is annoying.  Unlike basically every other Vulkan data return
    * method, we're not allowed to overwrite the client-provided memory region
    * on VK_INCOMPLETE.  This means we either need to query the blob size
    * up-front by serializing twice or we need to serialize into temporary
    * memory and memcpy into the client-provided region.  We choose the first
    * approach.
    *
    * In the common case, this means that vk_shader_ops::serialize will get
    * called 3 times: Once for the client to get the size, once for us to
    * validate the client's size, and once to actually write the data.  It's a
    * bit heavy-weight but this shouldn't be in a hot path and this is better
    * for memory efficiency.  Also, the vk_shader_ops::serialize should be
    * pretty fast on a null blob.
    */
   struct blob blob;
   blob_init_fixed(&blob, NULL, SIZE_MAX);
   result = vk_shader_serialize(device, shader, &blob);
   assert(result == VK_SUCCESS);

   if (result != VK_SUCCESS) {
      *pDataSize = 0;
      return result;
   } else if (pData == NULL) {
      *pDataSize = blob.size;
      return VK_SUCCESS;
   } else if (blob.size > *pDataSize) {
      /* No data written */
      *pDataSize = 0;
      return VK_INCOMPLETE;
   }

   blob_init_fixed(&blob, pData, *pDataSize);
   result = vk_shader_serialize(device, shader, &blob);
   assert(result == VK_SUCCESS);

   *pDataSize = blob.size;

   return result;
}

/* The only place where we have "real" linking is graphics shaders and there
 * is a limit as to how many of them can be linked together at one time.
 */
#define VK_MAX_LINKED_SHADER_STAGES MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES

const struct vk_pipeline_robustness_state vk_robustness_disabled = {
   .storage_buffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT,
   .uniform_buffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT,
   .vertex_inputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT,
   .images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT,
   /* From the Vulkan 1.3.292 spec:
    *
    *    "This extension [VK_EXT_robustness2] also adds support for “null
    *    descriptors”, where VK_NULL_HANDLE can be used instead of a valid
    *    handle. Accesses to null descriptors have well-defined behavior,
    *    and do not rely on robustness."
    *
    * For now, default these to true.
    */
   .null_uniform_buffer_descriptor = true,
   .null_storage_buffer_descriptor = true,
};

VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateShadersEXT(VkDevice _device,
                           uint32_t createInfoCount,
                           const VkShaderCreateInfoEXT *pCreateInfos,
                           const VkAllocationCallbacks *pAllocator,
                           VkShaderEXT *pShaders)
{
   VK_FROM_HANDLE(vk_device, device, _device);
   const struct vk_device_shader_ops *ops = device->shader_ops;
   VkResult first_fail_or_success = VK_SUCCESS;

   /* From the Vulkan 1.3.274 spec:
    *
    *    "When this function returns, whether or not it succeeds, it is
    *    guaranteed that every element of pShaders will have been overwritten
    *    by either VK_NULL_HANDLE or a valid VkShaderEXT handle."
    *
    * Zeroing up-front makes the error path easier.
    */
   memset(pShaders, 0, createInfoCount * sizeof(*pShaders));

   bool has_linked_spirv = false;
   for (uint32_t i = 0; i < createInfoCount; i++) {
      if (pCreateInfos[i].codeType == VK_SHADER_CODE_TYPE_SPIRV_EXT &&
          (pCreateInfos[i].flags & VK_SHADER_CREATE_LINK_STAGE_BIT_EXT))
         has_linked_spirv = true;
   }

   uint32_t linked_count = 0;
   struct stage_idx linked[VK_MAX_LINKED_SHADER_STAGES];

   for (uint32_t i = 0; i < createInfoCount; i++) {
      const VkShaderCreateInfoEXT *vk_info = &pCreateInfos[i];
      VkResult result = VK_SUCCESS;

      switch (vk_info->codeType) {
      case VK_SHADER_CODE_TYPE_BINARY_EXT: {
         /* This isn't required by Vulkan but we're allowed to fail binary
          * import for basically any reason.  This seems like a pretty good
          * reason.
          */
         if (has_linked_spirv &&
             (vk_info->flags & VK_SHADER_CREATE_LINK_STAGE_BIT_EXT)) {
            result = vk_errorf(device, VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT,
                               "Cannot mix linked binary and SPIR-V");
            break;
         }

         struct vk_shader *shader;
         result = vk_shader_deserialize(device, vk_info->codeSize,
                                        vk_info->pCode, pAllocator,
                                        &shader);
         if (result != VK_SUCCESS)
            break;

         pShaders[i] = vk_shader_to_handle(shader);
         break;
      }

      case VK_SHADER_CODE_TYPE_SPIRV_EXT: {
         if (vk_info->flags & VK_SHADER_CREATE_LINK_STAGE_BIT_EXT) {
            /* Stash it and compile later */
            assert(linked_count < ARRAY_SIZE(linked));
            linked[linked_count++] = (struct stage_idx) {
               .stage = vk_to_mesa_shader_stage(vk_info->stage),
               .idx = i,
            };
         } else {
            nir_shader *nir = vk_shader_to_nir(device, vk_info,
                                               &vk_robustness_disabled);
            if (nir == NULL) {
               result = vk_errorf(device, VK_ERROR_UNKNOWN,
                                  "Failed to compile shader to NIR");
               break;
            }

            struct vk_shader_compile_info info;
            struct set_layouts set_layouts;
            vk_shader_compile_info_init(&info, &set_layouts,
                                        vk_info, &vk_robustness_disabled, nir);

            struct vk_shader *shader;
            result = ops->compile(device, 1, &info, NULL /* state */,
                                  NULL /* features */, pAllocator, &shader);
            if (result != VK_SUCCESS)
               break;

            pShaders[i] = vk_shader_to_handle(shader);
         }
         break;
      }

      default:
         unreachable("Unknown shader code type");
      }

      if (first_fail_or_success == VK_SUCCESS)
         first_fail_or_success = result;
   }

   if (linked_count > 0) {
      struct set_layouts set_layouts[VK_MAX_LINKED_SHADER_STAGES];
      struct vk_shader_compile_info infos[VK_MAX_LINKED_SHADER_STAGES];
      VkResult result = VK_SUCCESS;

      /* Sort so we guarantee the driver always gets them in-order */
      qsort(linked, linked_count, sizeof(*linked), cmp_stage_idx);

      /* Memset for easy error handling */
      memset(infos, 0, sizeof(infos));

      for (uint32_t l = 0; l < linked_count; l++) {
         const VkShaderCreateInfoEXT *vk_info = &pCreateInfos[linked[l].idx];

         nir_shader *nir = vk_shader_to_nir(device, vk_info,
                                            &vk_robustness_disabled);
         if (nir == NULL) {
            result = vk_errorf(device, VK_ERROR_UNKNOWN,
                               "Failed to compile shader to NIR");
            break;
         }

         vk_shader_compile_info_init(&infos[l], &set_layouts[l],
                                     vk_info, &vk_robustness_disabled, nir);
      }

      if (result == VK_SUCCESS) {
         struct vk_shader *shaders[VK_MAX_LINKED_SHADER_STAGES];

         result = ops->compile(device, linked_count, infos, NULL /* state */,
                               NULL /* features */, pAllocator, shaders);
         if (result == VK_SUCCESS) {
            for (uint32_t l = 0; l < linked_count; l++)
               pShaders[linked[l].idx] = vk_shader_to_handle(shaders[l]);
         }
      } else {
         for (uint32_t l = 0; l < linked_count; l++) {
            if (infos[l].nir != NULL)
               ralloc_free(infos[l].nir);
         }
      }

      if (first_fail_or_success == VK_SUCCESS)
         first_fail_or_success = result;
   }

   return first_fail_or_success;
}

VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyShaderEXT(VkDevice _device,
                           VkShaderEXT _shader,
                           const VkAllocationCallbacks *pAllocator)
{
   VK_FROM_HANDLE(vk_device, device, _device);
   VK_FROM_HANDLE(vk_shader, shader, _shader);

   if (shader == NULL)
      return;

   vk_shader_destroy(device, shader, pAllocator);
}

VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBindShadersEXT(VkCommandBuffer commandBuffer,
                            uint32_t stageCount,
                            const VkShaderStageFlagBits *pStages,
                            const VkShaderEXT *pShaders)
{
   VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
   struct vk_device *device = cmd_buffer->base.device;
   const struct vk_device_shader_ops *ops = device->shader_ops;

   STACK_ARRAY(gl_shader_stage, stages, stageCount);
   STACK_ARRAY(struct vk_shader *, shaders, stageCount);

   VkShaderStageFlags vk_stages = 0;
   for (uint32_t i = 0; i < stageCount; i++) {
      vk_stages |= pStages[i];
      stages[i] = vk_to_mesa_shader_stage(pStages[i]);
      shaders[i] = pShaders != NULL ? vk_shader_from_handle(pShaders[i]) : NULL;
   }

   vk_cmd_unbind_pipelines_for_stages(cmd_buffer, vk_stages);
   if (vk_stages & ~VK_SHADER_STAGE_COMPUTE_BIT)
      vk_cmd_set_rp_attachments(cmd_buffer, ~0);

   ops->cmd_bind_shaders(cmd_buffer, stageCount, stages, shaders);
}
