/*
 * Copyright © 2017 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 "nir_spirv.h"

#include "vtn_private.h"
#include "spirv_info.h"

static bool
vtn_validate_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
                                  const uint32_t *w, unsigned count)
{
   switch (opcode) {
   case SpvOpSource:
   case SpvOpSourceExtension:
   case SpvOpSourceContinued:
   case SpvOpExtension:
   case SpvOpCapability:
   case SpvOpExtInstImport:
   case SpvOpMemoryModel:
   case SpvOpString:
   case SpvOpName:
   case SpvOpMemberName:
   case SpvOpExecutionMode:
   case SpvOpDecorationGroup:
   case SpvOpMemberDecorate:
   case SpvOpGroupDecorate:
   case SpvOpGroupMemberDecorate:
      break;

   case SpvOpEntryPoint:
      vtn_handle_entry_point(b, w, count);
      break;

   case SpvOpDecorate:
      vtn_handle_decoration(b, opcode, w, count);
      break;

   default:
      return false; /* End of preamble */
   }

   return true;
}

static void
spec_constant_decoration_cb(struct vtn_builder *b, struct vtn_value *v,
                            int member, const struct vtn_decoration *dec,
                            void *data)
{
   vtn_assert(member == -1);
   if (dec->decoration != SpvDecorationSpecId)
      return;

   for (unsigned i = 0; i < b->num_specializations; i++) {
      if (b->specializations[i].id == dec->literals[0]) {
         b->specializations[i].defined_on_module = true;
         return;
      }
   }
}

static void
vtn_validate_handle_constant(struct vtn_builder *b, SpvOp opcode,
                             const uint32_t *w, unsigned count)
{
   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);

   switch (opcode) {
   case SpvOpConstant:
   case SpvOpConstantNull:
   case SpvOpSpecConstantComposite:
   case SpvOpConstantComposite:
      /* Nothing to do here for gl_spirv needs */
      break;

   case SpvOpConstantTrue:
   case SpvOpConstantFalse:
   case SpvOpSpecConstantTrue:
   case SpvOpSpecConstantFalse:
   case SpvOpSpecConstant:
   case SpvOpSpecConstantOp:
      vtn_foreach_decoration(b, val, spec_constant_decoration_cb, NULL);
      break;

   case SpvOpConstantSampler:
      vtn_fail("OpConstantSampler requires Kernel Capability");
      break;

   default:
      vtn_fail("Unhandled opcode");
   }
}

static bool
vtn_validate_handle_constant_instruction(struct vtn_builder *b, SpvOp opcode,
                                         const uint32_t *w, unsigned count)
{
   switch (opcode) {
   case SpvOpSource:
   case SpvOpSourceContinued:
   case SpvOpSourceExtension:
   case SpvOpExtension:
   case SpvOpCapability:
   case SpvOpExtInstImport:
   case SpvOpMemoryModel:
   case SpvOpEntryPoint:
   case SpvOpExecutionMode:
   case SpvOpString:
   case SpvOpName:
   case SpvOpMemberName:
   case SpvOpDecorationGroup:
   case SpvOpDecorate:
   case SpvOpMemberDecorate:
   case SpvOpGroupDecorate:
   case SpvOpGroupMemberDecorate:
      vtn_fail("Invalid opcode types and variables section");
      break;

   case SpvOpTypeVoid:
   case SpvOpTypeBool:
   case SpvOpTypeInt:
   case SpvOpTypeFloat:
   case SpvOpTypeVector:
   case SpvOpTypeMatrix:
   case SpvOpTypeImage:
   case SpvOpTypeSampler:
   case SpvOpTypeSampledImage:
   case SpvOpTypeArray:
   case SpvOpTypeRuntimeArray:
   case SpvOpTypeStruct:
   case SpvOpTypeOpaque:
   case SpvOpTypePointer:
   case SpvOpTypeFunction:
   case SpvOpTypeEvent:
   case SpvOpTypeDeviceEvent:
   case SpvOpTypeReserveId:
   case SpvOpTypeQueue:
   case SpvOpTypePipe:
      /* We don't need to handle types */
      break;

   case SpvOpConstantTrue:
   case SpvOpConstantFalse:
   case SpvOpConstant:
   case SpvOpConstantComposite:
   case SpvOpConstantSampler:
   case SpvOpConstantNull:
   case SpvOpSpecConstantTrue:
   case SpvOpSpecConstantFalse:
   case SpvOpSpecConstant:
   case SpvOpSpecConstantComposite:
   case SpvOpSpecConstantOp:
      vtn_validate_handle_constant(b, opcode, w, count);
      break;

   case SpvOpUndef:
   case SpvOpVariable:
      /* We don't need to handle them */
      break;

   default:
      return false; /* End of preamble */
   }

   return true;
}

/*
 * Since OpenGL 4.6 you can use SPIR-V modules directly on OpenGL. One of the
 * new methods, glSpecializeShader include some possible errors when trying to
 * use it.
 *
 * From OpenGL 4.6, Section 7.2.1, "Shader Specialization":
 *
 * "void SpecializeShaderARB(uint shader,
 *                           const char* pEntryPoint,
 *                           uint numSpecializationConstants,
 *                           const uint* pConstantIndex,
 *                           const uint* pConstantValue);
 * <skip>
 *
 * INVALID_VALUE is generated if <pEntryPoint> does not name a valid
 * entry point for <shader>.
 *
 * An INVALID_VALUE error is generated if any element of pConstantIndex refers
 * to a specialization constant that does not exist in the shader module
 * contained in shader."
 *
 * We could do those checks on spirv_to_nir, but we are only interested on the
 * full translation later, during linking. This method is a simplified version
 * of spirv_to_nir, looking for only the checks needed by SpecializeShader.
 *
 * This method returns NULL if no entry point was found, and fill the
 * nir_spirv_specialization field "defined_on_module" accordingly. Caller
 * would need to trigger the specific errors.
 *
 */
bool
gl_spirv_validation(const uint32_t *words, size_t word_count,
                    struct nir_spirv_specialization *spec, unsigned num_spec,
                    gl_shader_stage stage, const char *entry_point_name)
{
   /* vtn_warn/vtn_log uses debug.func. Setting a null to prevent crash. Not
    * need to print the warnings now, would be done later, on the real
    * spirv_to_nir
    */
   const struct spirv_to_nir_options options = { .debug.func = NULL};
   const uint32_t *word_end = words + word_count;

   struct vtn_builder *b = vtn_create_builder(words, word_count,
                                              stage, entry_point_name,
                                              &options);

   if (b == NULL)
      return false;

   /* See also _vtn_fail() */
   if (setjmp(b->fail_jump)) {
      ralloc_free(b);
      return false;
   }

   /* Skip the SPIR-V header, handled at vtn_create_builder */
   words+= 5;

   /* Search entry point from preamble */
   words = vtn_foreach_instruction(b, words, word_end,
                                   vtn_validate_preamble_instruction);

   if (b->entry_point == NULL) {
      ralloc_free(b);
      return false;
   }

   b->specializations = spec;
   b->num_specializations = num_spec;

   /* Handle constant instructions (we don't need to handle
    * variables or types for gl_spirv)
    */
   words = vtn_foreach_instruction(b, words, word_end,
                                   vtn_validate_handle_constant_instruction);

   ralloc_free(b);

   return true;
}

