/*
 * Copyright © 2019 Red Hat.
 *
 * 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 "lvp_private.h"

#include "glsl_types.h"
#include "spirv/nir_spirv.h"
#include "nir/nir_builder.h"
#include "lvp_lower_vulkan_resource.h"
#include "pipe/p_state.h"
#include "pipe/p_context.h"

#define SPIR_V_MAGIC_NUMBER 0x07230203

VkResult lvp_CreateShaderModule(
   VkDevice                                    _device,
   const VkShaderModuleCreateInfo*             pCreateInfo,
   const VkAllocationCallbacks*                pAllocator,
   VkShaderModule*                             pShaderModule)
{
   LVP_FROM_HANDLE(lvp_device, device, _device);
   struct lvp_shader_module *module;

   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
   assert(pCreateInfo->flags == 0);

   module = vk_alloc2(&device->vk.alloc, pAllocator,
                      sizeof(*module) + pCreateInfo->codeSize, 8,
                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   if (module == NULL)
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);

   vk_object_base_init(&device->vk, &module->base,
                       VK_OBJECT_TYPE_SHADER_MODULE);
   module->size = pCreateInfo->codeSize;
   memcpy(module->data, pCreateInfo->pCode, module->size);

   *pShaderModule = lvp_shader_module_to_handle(module);

   return VK_SUCCESS;

}

void lvp_DestroyShaderModule(
   VkDevice                                    _device,
   VkShaderModule                              _module,
   const VkAllocationCallbacks*                pAllocator)
{
   LVP_FROM_HANDLE(lvp_device, device, _device);
   LVP_FROM_HANDLE(lvp_shader_module, module, _module);

   if (!_module)
      return;
   vk_object_base_finish(&module->base);
   vk_free2(&device->vk.alloc, pAllocator, module);
}

void lvp_DestroyPipeline(
   VkDevice                                    _device,
   VkPipeline                                  _pipeline,
   const VkAllocationCallbacks*                pAllocator)
{
   LVP_FROM_HANDLE(lvp_device, device, _device);
   LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline);

   if (!_pipeline)
      return;

   if (pipeline->shader_cso[PIPE_SHADER_VERTEX])
      device->queue.ctx->delete_vs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
   if (pipeline->shader_cso[PIPE_SHADER_FRAGMENT])
      device->queue.ctx->delete_fs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
   if (pipeline->shader_cso[PIPE_SHADER_GEOMETRY])
      device->queue.ctx->delete_gs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
   if (pipeline->shader_cso[PIPE_SHADER_TESS_CTRL])
      device->queue.ctx->delete_tcs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
   if (pipeline->shader_cso[PIPE_SHADER_TESS_EVAL])
      device->queue.ctx->delete_tes_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
   if (pipeline->shader_cso[PIPE_SHADER_COMPUTE])
      device->queue.ctx->delete_compute_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);

   if (!pipeline->is_compute_pipeline) {
      for (unsigned i = 0; i < pipeline->graphics_create_info.stageCount; i++)
         if (pipeline->graphics_create_info.pStages[i].pSpecializationInfo)
            free((void *)pipeline->graphics_create_info.pStages[i].pSpecializationInfo);

      free((void *)pipeline->graphics_create_info.pStages);
      free((void *)pipeline->graphics_create_info.pVertexInputState->pVertexBindingDescriptions);
      free((void *)pipeline->graphics_create_info.pVertexInputState->pVertexAttributeDescriptions);
      free((void *)pipeline->graphics_create_info.pVertexInputState);
      free((void *)pipeline->graphics_create_info.pInputAssemblyState);
      if (pipeline->graphics_create_info.pViewportState) {
         free((void *)pipeline->graphics_create_info.pViewportState->pViewports);
         free((void *)pipeline->graphics_create_info.pViewportState->pScissors);
      }
      free((void *)pipeline->graphics_create_info.pViewportState);

      if (pipeline->graphics_create_info.pTessellationState)
         free((void *)pipeline->graphics_create_info.pTessellationState);
      free((void *)pipeline->graphics_create_info.pRasterizationState);
      free((void *)pipeline->graphics_create_info.pMultisampleState);
      free((void *)pipeline->graphics_create_info.pDepthStencilState);
      if (pipeline->graphics_create_info.pColorBlendState)
         free((void *)pipeline->graphics_create_info.pColorBlendState->pAttachments);
      free((void *)pipeline->graphics_create_info.pColorBlendState);
      if (pipeline->graphics_create_info.pDynamicState)
         free((void *)pipeline->graphics_create_info.pDynamicState->pDynamicStates);
      free((void *)pipeline->graphics_create_info.pDynamicState);
   } else
      if (pipeline->compute_create_info.stage.pSpecializationInfo)
         free((void *)pipeline->compute_create_info.stage.pSpecializationInfo);
   vk_object_base_finish(&pipeline->base);
   vk_free2(&device->vk.alloc, pAllocator, pipeline);
}

static VkResult
deep_copy_shader_stage(struct VkPipelineShaderStageCreateInfo *dst,
                       const struct VkPipelineShaderStageCreateInfo *src)
{
   dst->sType = src->sType;
   dst->pNext = NULL;
   dst->flags = src->flags;
   dst->stage = src->stage;
   dst->module = src->module;
   dst->pName = src->pName;
   dst->pSpecializationInfo = NULL;
   if (src->pSpecializationInfo) {
      const VkSpecializationInfo *src_spec = src->pSpecializationInfo;
      VkSpecializationInfo *dst_spec = malloc(sizeof(VkSpecializationInfo) +
                                              src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry) +
                                              src_spec->dataSize);
      VkSpecializationMapEntry *maps = (VkSpecializationMapEntry *)(dst_spec + 1);
      dst_spec->pMapEntries = maps;
      void *pdata = (void *)(dst_spec->pMapEntries + src_spec->mapEntryCount);
      dst_spec->pData = pdata;


      dst_spec->mapEntryCount = src_spec->mapEntryCount;
      dst_spec->dataSize = src_spec->dataSize;
      memcpy(pdata, src_spec->pData, src->pSpecializationInfo->dataSize);
      memcpy(maps, src_spec->pMapEntries, src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry));
      dst->pSpecializationInfo = dst_spec;
   }
   return VK_SUCCESS;
}

static VkResult
deep_copy_vertex_input_state(struct VkPipelineVertexInputStateCreateInfo *dst,
                             const struct VkPipelineVertexInputStateCreateInfo *src)
{
   int i;
   VkVertexInputBindingDescription *dst_binding_descriptions;
   VkVertexInputAttributeDescription *dst_attrib_descriptions;
   dst->sType = src->sType;
   dst->pNext = NULL;
   dst->flags = src->flags;
   dst->vertexBindingDescriptionCount = src->vertexBindingDescriptionCount;

   dst_binding_descriptions = malloc(src->vertexBindingDescriptionCount * sizeof(VkVertexInputBindingDescription));
   if (!dst_binding_descriptions)
      return VK_ERROR_OUT_OF_HOST_MEMORY;
   for (i = 0; i < dst->vertexBindingDescriptionCount; i++) {
      memcpy(&dst_binding_descriptions[i], &src->pVertexBindingDescriptions[i], sizeof(VkVertexInputBindingDescription));
   }
   dst->pVertexBindingDescriptions = dst_binding_descriptions;

   dst->vertexAttributeDescriptionCount = src->vertexAttributeDescriptionCount;

   dst_attrib_descriptions = malloc(src->vertexAttributeDescriptionCount * sizeof(VkVertexInputAttributeDescription));
   if (!dst_attrib_descriptions)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   for (i = 0; i < dst->vertexAttributeDescriptionCount; i++) {
      memcpy(&dst_attrib_descriptions[i], &src->pVertexAttributeDescriptions[i], sizeof(VkVertexInputAttributeDescription));
   }
   dst->pVertexAttributeDescriptions = dst_attrib_descriptions;
   return VK_SUCCESS;
}

static VkResult
deep_copy_viewport_state(VkPipelineViewportStateCreateInfo *dst,
                         const VkPipelineViewportStateCreateInfo *src)
{
   int i;
   VkViewport *viewports;
   VkRect2D *scissors;
   dst->sType = src->sType;
   dst->pNext = src->pNext;

   dst->flags = src->flags;

   if (src->pViewports) {
      viewports = malloc(src->viewportCount * sizeof(VkViewport));
      for (i = 0; i < src->viewportCount; i++)
         memcpy(&viewports[i], &src->pViewports[i], sizeof(VkViewport));
      dst->pViewports = viewports;
   } else
      dst->pViewports = NULL;
   dst->viewportCount = src->viewportCount;

   if (src->pScissors) {
      scissors = malloc(src->scissorCount * sizeof(VkRect2D));
      for (i = 0; i < src->scissorCount; i++)
         memcpy(&scissors[i], &src->pScissors[i], sizeof(VkRect2D));
      dst->pScissors = scissors;
   } else
      dst->pScissors = NULL;
   dst->scissorCount = src->scissorCount;

   return VK_SUCCESS;
}

static VkResult
deep_copy_color_blend_state(VkPipelineColorBlendStateCreateInfo *dst,
                            const VkPipelineColorBlendStateCreateInfo *src)
{
   VkPipelineColorBlendAttachmentState *attachments;
   dst->sType = src->sType;
   dst->pNext = src->pNext;
   dst->flags = src->flags;
   dst->logicOpEnable = src->logicOpEnable;
   dst->logicOp = src->logicOp;

   attachments = malloc(src->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState));
   memcpy(attachments, src->pAttachments, src->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState));
   dst->attachmentCount = src->attachmentCount;
   dst->pAttachments = attachments;

   memcpy(&dst->blendConstants, &src->blendConstants, sizeof(float) * 4);

   return VK_SUCCESS;
}

static VkResult
deep_copy_dynamic_state(VkPipelineDynamicStateCreateInfo *dst,
                        const VkPipelineDynamicStateCreateInfo *src)
{
   VkDynamicState *dynamic_states;
   dst->sType = src->sType;
   dst->pNext = src->pNext;
   dst->flags = src->flags;

   dynamic_states = malloc(src->dynamicStateCount * sizeof(VkDynamicState));
   if (!dynamic_states)
      return VK_ERROR_OUT_OF_HOST_MEMORY;

   memcpy(dynamic_states, src->pDynamicStates, src->dynamicStateCount * sizeof(VkDynamicState));
   dst->dynamicStateCount = src->dynamicStateCount;
   dst->pDynamicStates = dynamic_states;
   return VK_SUCCESS;
}

static VkResult
deep_copy_graphics_create_info(VkGraphicsPipelineCreateInfo *dst,
                               const VkGraphicsPipelineCreateInfo *src)
{
   int i;
   VkResult result;
   VkPipelineShaderStageCreateInfo *stages;
   VkPipelineVertexInputStateCreateInfo *vertex_input;
   VkPipelineInputAssemblyStateCreateInfo *input_assembly;
   VkPipelineRasterizationStateCreateInfo* raster_state;

   dst->sType = src->sType;
   dst->pNext = NULL;
   dst->flags = src->flags;
   dst->layout = src->layout;
   dst->renderPass = src->renderPass;
   dst->subpass = src->subpass;
   dst->basePipelineHandle = src->basePipelineHandle;
   dst->basePipelineIndex = src->basePipelineIndex;

   /* pStages */
   dst->stageCount = src->stageCount;
   stages = malloc(dst->stageCount * sizeof(VkPipelineShaderStageCreateInfo));
   for (i = 0 ; i < dst->stageCount; i++) {
      result = deep_copy_shader_stage(&stages[i], &src->pStages[i]);
      if (result != VK_SUCCESS)
         return result;
   }
   dst->pStages = stages;

   /* pVertexInputState */
   vertex_input = malloc(sizeof(VkPipelineVertexInputStateCreateInfo));
   result = deep_copy_vertex_input_state(vertex_input,
                                         src->pVertexInputState);
   if (result != VK_SUCCESS)
      return result;
   dst->pVertexInputState = vertex_input;

   /* pInputAssemblyState */
   input_assembly = malloc(sizeof(VkPipelineInputAssemblyStateCreateInfo));
   if (!input_assembly)
      return VK_ERROR_OUT_OF_HOST_MEMORY;
   memcpy(input_assembly, src->pInputAssemblyState, sizeof(VkPipelineInputAssemblyStateCreateInfo));
   dst->pInputAssemblyState = input_assembly;

   /* pTessellationState */
   if (src->pTessellationState) {
      VkPipelineTessellationStateCreateInfo *tess_state;
      tess_state = malloc(sizeof(VkPipelineTessellationStateCreateInfo));
      if (!tess_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      memcpy(tess_state, src->pTessellationState, sizeof(VkPipelineTessellationStateCreateInfo));
      dst->pTessellationState = tess_state;
   }


   /* pViewportState */
   if (src->pViewportState) {
      VkPipelineViewportStateCreateInfo *viewport_state;
      viewport_state = malloc(sizeof(VkPipelineViewportStateCreateInfo));
      if (!viewport_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      deep_copy_viewport_state(viewport_state, src->pViewportState);
      dst->pViewportState = viewport_state;
   } else
      dst->pViewportState = NULL;

   /* pRasterizationState */
   raster_state = malloc(sizeof(VkPipelineRasterizationStateCreateInfo));
   if (!raster_state)
      return VK_ERROR_OUT_OF_HOST_MEMORY;
   memcpy(raster_state, src->pRasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo));
   dst->pRasterizationState = raster_state;

   /* pMultisampleState */
   if (src->pMultisampleState) {
      VkPipelineMultisampleStateCreateInfo*   ms_state;
      ms_state = malloc(sizeof(VkPipelineMultisampleStateCreateInfo) + sizeof(VkSampleMask));
      if (!ms_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      /* does samplemask need deep copy? */
      memcpy(ms_state, src->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
      if (src->pMultisampleState->pSampleMask) {
         VkSampleMask *sample_mask = (VkSampleMask *)(ms_state + 1);
         sample_mask[0] = src->pMultisampleState->pSampleMask[0];
         ms_state->pSampleMask = sample_mask;
      }
      dst->pMultisampleState = ms_state;
   } else
      dst->pMultisampleState = NULL;

   /* pDepthStencilState */
   if (src->pDepthStencilState) {
      VkPipelineDepthStencilStateCreateInfo*  ds_state;

      ds_state = malloc(sizeof(VkPipelineDepthStencilStateCreateInfo));
      if (!ds_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      memcpy(ds_state, src->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo));
      dst->pDepthStencilState = ds_state;
   } else
      dst->pDepthStencilState = NULL;

   /* pColorBlendState */
   if (src->pColorBlendState) {
      VkPipelineColorBlendStateCreateInfo*    cb_state;

      cb_state = malloc(sizeof(VkPipelineColorBlendStateCreateInfo));
      if (!cb_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      deep_copy_color_blend_state(cb_state, src->pColorBlendState);
      dst->pColorBlendState = cb_state;
   } else
      dst->pColorBlendState = NULL;

   if (src->pDynamicState) {
      VkPipelineDynamicStateCreateInfo*       dyn_state;

      /* pDynamicState */
      dyn_state = malloc(sizeof(VkPipelineDynamicStateCreateInfo));
      if (!dyn_state)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
      deep_copy_dynamic_state(dyn_state, src->pDynamicState);
      dst->pDynamicState = dyn_state;
   } else
      dst->pDynamicState = NULL;

   return VK_SUCCESS;
}

static VkResult
deep_copy_compute_create_info(VkComputePipelineCreateInfo *dst,
                              const VkComputePipelineCreateInfo *src)
{
   VkResult result;
   dst->sType = src->sType;
   dst->pNext = NULL;
   dst->flags = src->flags;
   dst->layout = src->layout;
   dst->basePipelineHandle = src->basePipelineHandle;
   dst->basePipelineIndex = src->basePipelineIndex;

   result = deep_copy_shader_stage(&dst->stage, &src->stage);
   if (result != VK_SUCCESS)
      return result;
   return VK_SUCCESS;
}

static inline unsigned
st_shader_stage_to_ptarget(gl_shader_stage stage)
{
   switch (stage) {
   case MESA_SHADER_VERTEX:
      return PIPE_SHADER_VERTEX;
   case MESA_SHADER_FRAGMENT:
      return PIPE_SHADER_FRAGMENT;
   case MESA_SHADER_GEOMETRY:
      return PIPE_SHADER_GEOMETRY;
   case MESA_SHADER_TESS_CTRL:
      return PIPE_SHADER_TESS_CTRL;
   case MESA_SHADER_TESS_EVAL:
      return PIPE_SHADER_TESS_EVAL;
   case MESA_SHADER_COMPUTE:
      return PIPE_SHADER_COMPUTE;
   default:
      break;
   }

   assert(!"should not be reached");
   return PIPE_SHADER_VERTEX;
}

static void
shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align)
{
   assert(glsl_type_is_vector_or_scalar(type));

   uint32_t comp_size = glsl_type_is_boolean(type)
      ? 4 : glsl_get_bit_size(type) / 8;
   unsigned length = glsl_get_vector_elements(type);
   *size = comp_size * length,
      *align = comp_size;
}

#define OPT(pass, ...) ({                                       \
         bool this_progress = false;                            \
         NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__);     \
         if (this_progress)                                     \
            progress = true;                                    \
         this_progress;                                         \
      })

static void
lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
                         struct lvp_shader_module *module,
                         const char *entrypoint_name,
                         gl_shader_stage stage,
                         const VkSpecializationInfo *spec_info)
{
   nir_shader *nir;
   const nir_shader_compiler_options *drv_options = pipeline->device->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
   bool progress;
   uint32_t *spirv = (uint32_t *) module->data;
   assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
   assert(module->size % 4 == 0);

   uint32_t num_spec_entries = 0;
   struct nir_spirv_specialization *spec_entries = NULL;
   if (spec_info && spec_info->mapEntryCount > 0) {
      num_spec_entries = spec_info->mapEntryCount;
      spec_entries = calloc(num_spec_entries, sizeof(*spec_entries));
      for (uint32_t i = 0; i < num_spec_entries; i++) {
         VkSpecializationMapEntry entry = spec_info->pMapEntries[i];
         const void *data =
            spec_info->pData + entry.offset;
         assert((const void *)(data + entry.size) <=
                spec_info->pData + spec_info->dataSize);

         spec_entries[i].id = entry.constantID;
         switch (entry.size) {
         case 8:
            spec_entries[i].value.u64 = *(const uint64_t *)data;
            break;
         case 4:
            spec_entries[i].value.u32 = *(const uint32_t *)data;
            break;
         case 2:
            spec_entries[i].value.u16 = *(const uint16_t *)data;
            break;
         case 1:
            spec_entries[i].value.u8 = *(const uint8_t *)data;
            break;
         default:
            assert(!"Invalid spec constant size");
            break;
         }
      }
   }
   struct lvp_device *pdevice = pipeline->device;
   const struct spirv_to_nir_options spirv_options = {
      .environment = NIR_SPIRV_VULKAN,
      .caps = {
         .float64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
         .int16 = true,
         .int64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
         .tessellation = true,
         .image_ms_array = true,
         .storage_image_ms = true,
         .geometry_streams = true,
         .storage_16bit = true,
         .variable_pointers = true,
      },
      .ubo_addr_format = nir_address_format_32bit_index_offset,
      .ssbo_addr_format = nir_address_format_32bit_index_offset,
      .phys_ssbo_addr_format = nir_address_format_64bit_global,
      .push_const_addr_format = nir_address_format_logical,
      .shared_addr_format = nir_address_format_32bit_offset,
      .frag_coord_is_sysval = false,
   };

   nir = spirv_to_nir(spirv, module->size / 4,
                      spec_entries, num_spec_entries,
                      stage, entrypoint_name, &spirv_options, drv_options);

   nir_validate_shader(nir, NULL);

   free(spec_entries);

   NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
   NIR_PASS_V(nir, nir_lower_returns);
   NIR_PASS_V(nir, nir_inline_functions);
   NIR_PASS_V(nir, nir_copy_prop);
   NIR_PASS_V(nir, nir_opt_deref);

   /* Pick off the single entrypoint that we want */
   foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
      if (!func->is_entrypoint)
         exec_node_remove(&func->node);
   }
   assert(exec_list_length(&nir->functions) == 1);

   NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
   NIR_PASS_V(nir, nir_split_var_copies);
   NIR_PASS_V(nir, nir_split_per_member_structs);

   NIR_PASS_V(nir, nir_remove_dead_variables,
              nir_var_shader_in | nir_var_shader_out | nir_var_system_value, NULL);

   if (stage == MESA_SHADER_FRAGMENT)
      lvp_lower_input_attachments(nir, false);
   NIR_PASS_V(nir, nir_lower_system_values);
   NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);

   NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
   nir_remove_dead_variables(nir, nir_var_uniform, NULL);

   lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);

   NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
   NIR_PASS_V(nir, nir_split_var_copies);
   NIR_PASS_V(nir, nir_lower_global_vars_to_local);

   NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const,
              nir_address_format_32bit_offset);

   NIR_PASS_V(nir, nir_lower_explicit_io,
              nir_var_mem_ubo | nir_var_mem_ssbo,
              nir_address_format_32bit_index_offset);

   if (nir->info.stage == MESA_SHADER_COMPUTE) {
      NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_var_info);
      NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset);
   }

   NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL);

   if (nir->info.stage == MESA_SHADER_VERTEX ||
       nir->info.stage == MESA_SHADER_GEOMETRY) {
      NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
   } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
      NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
   }

   do {
      progress = false;

      progress |= OPT(nir_lower_flrp, 32|64, true);
      progress |= OPT(nir_split_array_vars, nir_var_function_temp);
      progress |= OPT(nir_shrink_vec_array_vars, nir_var_function_temp);
      progress |= OPT(nir_opt_deref);
      progress |= OPT(nir_lower_vars_to_ssa);

      progress |= nir_copy_prop(nir);
      progress |= nir_opt_dce(nir);
      progress |= nir_opt_dead_cf(nir);
      progress |= nir_opt_cse(nir);
      progress |= nir_opt_algebraic(nir);
      progress |= nir_opt_constant_folding(nir);
      progress |= nir_opt_undef(nir);

      progress |= nir_opt_deref(nir);
      progress |= nir_lower_alu_to_scalar(nir, NULL, NULL);
   } while (progress);

   nir_lower_var_copies(nir);
   nir_remove_dead_variables(nir, nir_var_function_temp, NULL);

   nir_validate_shader(nir, NULL);
   nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));

   if (nir->info.stage != MESA_SHADER_VERTEX)
      nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
   else {
      nir->num_inputs = util_last_bit64(nir->info.inputs_read);
      nir_foreach_shader_in_variable(var, nir) {
         var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
      }
   }
   nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
                               nir->info.stage);
   pipeline->pipeline_nir[stage] = nir;
}

static void fill_shader_prog(struct pipe_shader_state *state, gl_shader_stage stage, struct lvp_pipeline *pipeline)
{
   state->type = PIPE_SHADER_IR_NIR;
   state->ir.nir = pipeline->pipeline_nir[stage];
}

static void
merge_tess_info(struct shader_info *tes_info,
                const struct shader_info *tcs_info)
{
   /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
    *
    *    "PointMode. Controls generation of points rather than triangles
    *     or lines. This functionality defaults to disabled, and is
    *     enabled if either shader stage includes the execution mode.
    *
    * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
    * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
    * and OutputVertices, it says:
    *
    *    "One mode must be set in at least one of the tessellation
    *     shader stages."
    *
    * So, the fields can be set in either the TCS or TES, but they must
    * agree if set in both.  Our backend looks at TES, so bitwise-or in
    * the values from the TCS.
    */
   assert(tcs_info->tess.tcs_vertices_out == 0 ||
          tes_info->tess.tcs_vertices_out == 0 ||
          tcs_info->tess.tcs_vertices_out == tes_info->tess.tcs_vertices_out);
   tes_info->tess.tcs_vertices_out |= tcs_info->tess.tcs_vertices_out;

   assert(tcs_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
          tes_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
          tcs_info->tess.spacing == tes_info->tess.spacing);
   tes_info->tess.spacing |= tcs_info->tess.spacing;

   assert(tcs_info->tess.primitive_mode == 0 ||
          tes_info->tess.primitive_mode == 0 ||
          tcs_info->tess.primitive_mode == tes_info->tess.primitive_mode);
   tes_info->tess.primitive_mode |= tcs_info->tess.primitive_mode;
   tes_info->tess.ccw |= tcs_info->tess.ccw;
   tes_info->tess.point_mode |= tcs_info->tess.point_mode;
}

static gl_shader_stage
lvp_shader_stage(VkShaderStageFlagBits stage)
{
   switch (stage) {
   case VK_SHADER_STAGE_VERTEX_BIT:
      return MESA_SHADER_VERTEX;
   case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
      return MESA_SHADER_TESS_CTRL;
   case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
      return MESA_SHADER_TESS_EVAL;
   case VK_SHADER_STAGE_GEOMETRY_BIT:
      return MESA_SHADER_GEOMETRY;
   case VK_SHADER_STAGE_FRAGMENT_BIT:
      return MESA_SHADER_FRAGMENT;
   case VK_SHADER_STAGE_COMPUTE_BIT:
      return MESA_SHADER_COMPUTE;
   default:
      unreachable("invalid VkShaderStageFlagBits");
      return MESA_SHADER_NONE;
   }
}

static VkResult
lvp_pipeline_compile(struct lvp_pipeline *pipeline,
                     gl_shader_stage stage)
{
   struct lvp_device *device = pipeline->device;
   device->physical_device->pscreen->finalize_nir(device->physical_device->pscreen, pipeline->pipeline_nir[stage], true);
   if (stage == MESA_SHADER_COMPUTE) {
      struct pipe_compute_state shstate = {};
      shstate.prog = (void *)pipeline->pipeline_nir[MESA_SHADER_COMPUTE];
      shstate.ir_type = PIPE_SHADER_IR_NIR;
      shstate.req_local_mem = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.cs.shared_size;
      pipeline->shader_cso[PIPE_SHADER_COMPUTE] = device->queue.ctx->create_compute_state(device->queue.ctx, &shstate);
   } else {
      struct pipe_shader_state shstate = {};
      fill_shader_prog(&shstate, stage, pipeline);
      switch (stage) {
      case MESA_SHADER_FRAGMENT:
         pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
         break;
      case MESA_SHADER_VERTEX:
         pipeline->shader_cso[PIPE_SHADER_VERTEX] = device->queue.ctx->create_vs_state(device->queue.ctx, &shstate);
         break;
      case MESA_SHADER_GEOMETRY:
         pipeline->shader_cso[PIPE_SHADER_GEOMETRY] = device->queue.ctx->create_gs_state(device->queue.ctx, &shstate);
         break;
      case MESA_SHADER_TESS_CTRL:
         pipeline->shader_cso[PIPE_SHADER_TESS_CTRL] = device->queue.ctx->create_tcs_state(device->queue.ctx, &shstate);
         break;
      case MESA_SHADER_TESS_EVAL:
         pipeline->shader_cso[PIPE_SHADER_TESS_EVAL] = device->queue.ctx->create_tes_state(device->queue.ctx, &shstate);
         break;
      default:
         unreachable("illegal shader");
         break;
      }
   }
   return VK_SUCCESS;
}

static VkResult
lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
                           struct lvp_device *device,
                           struct lvp_pipeline_cache *cache,
                           const VkGraphicsPipelineCreateInfo *pCreateInfo,
                           const VkAllocationCallbacks *alloc)
{
   if (alloc == NULL)
      alloc = &device->vk.alloc;
   pipeline->device = device;
   pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
   pipeline->force_min_sample = false;

   /* recreate createinfo */
   deep_copy_graphics_create_info(&pipeline->graphics_create_info, pCreateInfo);
   pipeline->is_compute_pipeline = false;

   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
      LVP_FROM_HANDLE(lvp_shader_module, module,
                      pCreateInfo->pStages[i].module);
      gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
      lvp_shader_compile_to_ir(pipeline, module,
                               pCreateInfo->pStages[i].pName,
                               stage,
                               pCreateInfo->pStages[i].pSpecializationInfo);
   }

   if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]) {
      if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.fs.uses_sample_qualifier ||
          pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID |
                                                                                   SYSTEM_BIT_SAMPLE_POS))
         pipeline->force_min_sample = true;
   }
   if (pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]) {
      nir_lower_patch_vertices(pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL], pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out, NULL);
      merge_tess_info(&pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info, &pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info);
      pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw = !pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw;
   }


   bool has_fragment_shader = false;
   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
      gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
      lvp_pipeline_compile(pipeline, stage);
      if (stage == MESA_SHADER_FRAGMENT)
         has_fragment_shader = true;
   }

   if (has_fragment_shader == false) {
      /* create a dummy fragment shader for this pipeline. */
      nir_builder b;

      nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
      b.shader->info.name = ralloc_strdup(b.shader, "dummy_frag");

      pipeline->pipeline_nir[MESA_SHADER_FRAGMENT] = b.shader;
      struct pipe_shader_state shstate = {};
      shstate.type = PIPE_SHADER_IR_NIR;
      shstate.ir.nir = pipeline->pipeline_nir[MESA_SHADER_FRAGMENT];
      pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
   }
   return VK_SUCCESS;
}

static VkResult
lvp_graphics_pipeline_create(
   VkDevice _device,
   VkPipelineCache _cache,
   const VkGraphicsPipelineCreateInfo *pCreateInfo,
   const VkAllocationCallbacks *pAllocator,
   VkPipeline *pPipeline)
{
   LVP_FROM_HANDLE(lvp_device, device, _device);
   LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
   struct lvp_pipeline *pipeline;
   VkResult result;

   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);

   pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   if (pipeline == NULL)
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);

   vk_object_base_init(&device->vk, &pipeline->base,
                       VK_OBJECT_TYPE_PIPELINE);
   result = lvp_graphics_pipeline_init(pipeline, device, cache, pCreateInfo,
                                       pAllocator);
   if (result != VK_SUCCESS) {
      vk_free2(&device->vk.alloc, pAllocator, pipeline);
      return result;
   }

   *pPipeline = lvp_pipeline_to_handle(pipeline);

   return VK_SUCCESS;
}

VkResult lvp_CreateGraphicsPipelines(
   VkDevice                                    _device,
   VkPipelineCache                             pipelineCache,
   uint32_t                                    count,
   const VkGraphicsPipelineCreateInfo*         pCreateInfos,
   const VkAllocationCallbacks*                pAllocator,
   VkPipeline*                                 pPipelines)
{
   VkResult result = VK_SUCCESS;
   unsigned i = 0;

   for (; i < count; i++) {
      VkResult r;
      r = lvp_graphics_pipeline_create(_device,
                                       pipelineCache,
                                       &pCreateInfos[i],
                                       pAllocator, &pPipelines[i]);
      if (r != VK_SUCCESS) {
         result = r;
         pPipelines[i] = VK_NULL_HANDLE;
      }
   }

   return result;
}

static VkResult
lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
                          struct lvp_device *device,
                          struct lvp_pipeline_cache *cache,
                          const VkComputePipelineCreateInfo *pCreateInfo,
                          const VkAllocationCallbacks *alloc)
{
   LVP_FROM_HANDLE(lvp_shader_module, module,
                   pCreateInfo->stage.module);
   if (alloc == NULL)
      alloc = &device->vk.alloc;
   pipeline->device = device;
   pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
   pipeline->force_min_sample = false;

   deep_copy_compute_create_info(&pipeline->compute_create_info, pCreateInfo);
   pipeline->is_compute_pipeline = true;

   lvp_shader_compile_to_ir(pipeline, module,
                            pCreateInfo->stage.pName,
                            MESA_SHADER_COMPUTE,
                            pCreateInfo->stage.pSpecializationInfo);
   lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
   return VK_SUCCESS;
}

static VkResult
lvp_compute_pipeline_create(
   VkDevice _device,
   VkPipelineCache _cache,
   const VkComputePipelineCreateInfo *pCreateInfo,
   const VkAllocationCallbacks *pAllocator,
   VkPipeline *pPipeline)
{
   LVP_FROM_HANDLE(lvp_device, device, _device);
   LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
   struct lvp_pipeline *pipeline;
   VkResult result;

   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);

   pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   if (pipeline == NULL)
      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);

   vk_object_base_init(&device->vk, &pipeline->base,
                       VK_OBJECT_TYPE_PIPELINE);
   result = lvp_compute_pipeline_init(pipeline, device, cache, pCreateInfo,
                                      pAllocator);
   if (result != VK_SUCCESS) {
      vk_free2(&device->vk.alloc, pAllocator, pipeline);
      return result;
   }

   *pPipeline = lvp_pipeline_to_handle(pipeline);

   return VK_SUCCESS;
}

VkResult lvp_CreateComputePipelines(
   VkDevice                                    _device,
   VkPipelineCache                             pipelineCache,
   uint32_t                                    count,
   const VkComputePipelineCreateInfo*          pCreateInfos,
   const VkAllocationCallbacks*                pAllocator,
   VkPipeline*                                 pPipelines)
{
   VkResult result = VK_SUCCESS;
   unsigned i = 0;

   for (; i < count; i++) {
      VkResult r;
      r = lvp_compute_pipeline_create(_device,
                                      pipelineCache,
                                      &pCreateInfos[i],
                                      pAllocator, &pPipelines[i]);
      if (r != VK_SUCCESS) {
         result = r;
         pPipelines[i] = VK_NULL_HANDLE;
      }
   }

   return result;
}
