Home | History | Annotate | Line # | Download | only in vulkan
      1 /*
      2  * Copyright  2019 Raspberry Pi
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  */
     23 
     24 #include "vk_util.h"
     25 
     26 #include "v3dv_debug.h"
     27 #include "v3dv_private.h"
     28 
     29 #include "vk_format_info.h"
     30 
     31 #include "common/v3d_debug.h"
     32 
     33 #include "compiler/nir/nir_builder.h"
     34 #include "nir/nir_serialize.h"
     35 
     36 #include "util/u_atomic.h"
     37 #include "util/u_prim.h"
     38 #include "util/os_time.h"
     39 
     40 #include "vulkan/util/vk_format.h"
     41 
     42 static VkResult
     43 compute_vpm_config(struct v3dv_pipeline *pipeline);
     44 
     45 void
     46 v3dv_print_v3d_key(struct v3d_key *key,
     47                    uint32_t v3d_key_size)
     48 {
     49    struct mesa_sha1 ctx;
     50    unsigned char sha1[20];
     51    char sha1buf[41];
     52 
     53    _mesa_sha1_init(&ctx);
     54 
     55    _mesa_sha1_update(&ctx, key, v3d_key_size);
     56 
     57    _mesa_sha1_final(&ctx, sha1);
     58    _mesa_sha1_format(sha1buf, sha1);
     59 
     60    fprintf(stderr, "key %p: %s\n", key, sha1buf);
     61 }
     62 
     63 static void
     64 pipeline_compute_sha1_from_nir(nir_shader *nir,
     65                                unsigned char sha1[20])
     66 {
     67    assert(nir);
     68    struct blob blob;
     69    blob_init(&blob);
     70 
     71    nir_serialize(&blob, nir, false);
     72    if (!blob.out_of_memory)
     73       _mesa_sha1_compute(blob.data, blob.size, sha1);
     74 
     75    blob_finish(&blob);
     76 }
     77 
     78 void
     79 v3dv_shader_module_internal_init(struct v3dv_device *device,
     80                                  struct vk_shader_module *module,
     81                                  nir_shader *nir)
     82 {
     83    vk_object_base_init(&device->vk, &module->base,
     84                        VK_OBJECT_TYPE_SHADER_MODULE);
     85    module->nir = nir;
     86    module->size = 0;
     87 
     88    pipeline_compute_sha1_from_nir(nir, module->sha1);
     89 }
     90 
     91 void
     92 v3dv_shader_variant_destroy(struct v3dv_device *device,
     93                             struct v3dv_shader_variant *variant)
     94 {
     95    /* The assembly BO is shared by all variants in the pipeline, so it can't
     96     * be freed here and should be freed with the pipeline
     97     */
     98    ralloc_free(variant->prog_data.base);
     99    vk_free(&device->vk.alloc, variant);
    100 }
    101 
    102 static void
    103 destroy_pipeline_stage(struct v3dv_device *device,
    104                        struct v3dv_pipeline_stage *p_stage,
    105                        const VkAllocationCallbacks *pAllocator)
    106 {
    107    if (!p_stage)
    108       return;
    109 
    110    ralloc_free(p_stage->nir);
    111    vk_free2(&device->vk.alloc, pAllocator, p_stage);
    112 }
    113 
    114 static void
    115 pipeline_free_stages(struct v3dv_device *device,
    116                      struct v3dv_pipeline *pipeline,
    117                      const VkAllocationCallbacks *pAllocator)
    118 {
    119    assert(pipeline);
    120 
    121    /* FIXME: we can't just use a loop over mesa stage due the bin, would be
    122     * good to find an alternative.
    123     */
    124    destroy_pipeline_stage(device, pipeline->vs, pAllocator);
    125    destroy_pipeline_stage(device, pipeline->vs_bin, pAllocator);
    126    destroy_pipeline_stage(device, pipeline->gs, pAllocator);
    127    destroy_pipeline_stage(device, pipeline->gs_bin, pAllocator);
    128    destroy_pipeline_stage(device, pipeline->fs, pAllocator);
    129    destroy_pipeline_stage(device, pipeline->cs, pAllocator);
    130 
    131    pipeline->vs = NULL;
    132    pipeline->vs_bin = NULL;
    133    pipeline->gs = NULL;
    134    pipeline->gs_bin = NULL;
    135    pipeline->fs = NULL;
    136    pipeline->cs = NULL;
    137 }
    138 
    139 static void
    140 v3dv_destroy_pipeline(struct v3dv_pipeline *pipeline,
    141                       struct v3dv_device *device,
    142                       const VkAllocationCallbacks *pAllocator)
    143 {
    144    if (!pipeline)
    145       return;
    146 
    147    pipeline_free_stages(device, pipeline, pAllocator);
    148 
    149    if (pipeline->shared_data) {
    150       v3dv_pipeline_shared_data_unref(device, pipeline->shared_data);
    151       pipeline->shared_data = NULL;
    152    }
    153 
    154    if (pipeline->spill.bo) {
    155       assert(pipeline->spill.size_per_thread > 0);
    156       v3dv_bo_free(device, pipeline->spill.bo);
    157    }
    158 
    159    if (pipeline->default_attribute_values) {
    160       v3dv_bo_free(device, pipeline->default_attribute_values);
    161       pipeline->default_attribute_values = NULL;
    162    }
    163 
    164    vk_object_free(&device->vk, pAllocator, pipeline);
    165 }
    166 
    167 VKAPI_ATTR void VKAPI_CALL
    168 v3dv_DestroyPipeline(VkDevice _device,
    169                      VkPipeline _pipeline,
    170                      const VkAllocationCallbacks *pAllocator)
    171 {
    172    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    173    V3DV_FROM_HANDLE(v3dv_pipeline, pipeline, _pipeline);
    174 
    175    if (!pipeline)
    176       return;
    177 
    178    v3dv_destroy_pipeline(pipeline, device, pAllocator);
    179 }
    180 
    181 static const struct spirv_to_nir_options default_spirv_options =  {
    182    .caps = {
    183       .device_group = true,
    184       .multiview = true,
    185       .subgroup_basic = true,
    186       .variable_pointers = true,
    187     },
    188    .ubo_addr_format = nir_address_format_32bit_index_offset,
    189    .ssbo_addr_format = nir_address_format_32bit_index_offset,
    190    .phys_ssbo_addr_format = nir_address_format_64bit_global,
    191    .push_const_addr_format = nir_address_format_logical,
    192    .shared_addr_format = nir_address_format_32bit_offset,
    193 };
    194 
    195 const nir_shader_compiler_options v3dv_nir_options = {
    196    .lower_uadd_sat = true,
    197    .lower_iadd_sat = true,
    198    .lower_all_io_to_temps = true,
    199    .lower_extract_byte = true,
    200    .lower_extract_word = true,
    201    .lower_insert_byte = true,
    202    .lower_insert_word = true,
    203    .lower_bitfield_insert_to_shifts = true,
    204    .lower_bitfield_extract_to_shifts = true,
    205    .lower_bitfield_reverse = true,
    206    .lower_bit_count = true,
    207    .lower_cs_local_id_from_index = true,
    208    .lower_ffract = true,
    209    .lower_fmod = true,
    210    .lower_pack_unorm_2x16 = true,
    211    .lower_pack_snorm_2x16 = true,
    212    .lower_unpack_unorm_2x16 = true,
    213    .lower_unpack_snorm_2x16 = true,
    214    .lower_pack_unorm_4x8 = true,
    215    .lower_pack_snorm_4x8 = true,
    216    .lower_unpack_unorm_4x8 = true,
    217    .lower_unpack_snorm_4x8 = true,
    218    .lower_pack_half_2x16 = true,
    219    .lower_unpack_half_2x16 = true,
    220    /* FIXME: see if we can avoid the uadd_carry and usub_borrow lowering and
    221     * get the tests to pass since it might produce slightly better code.
    222     */
    223    .lower_uadd_carry = true,
    224    .lower_usub_borrow = true,
    225    /* FIXME: check if we can use multop + umul24 to implement mul2x32_64
    226     * without lowering.
    227     */
    228    .lower_mul_2x32_64 = true,
    229    .lower_fdiv = true,
    230    .lower_find_lsb = true,
    231    .lower_ffma16 = true,
    232    .lower_ffma32 = true,
    233    .lower_ffma64 = true,
    234    .lower_flrp32 = true,
    235    .lower_fpow = true,
    236    .lower_fsat = true,
    237    .lower_fsqrt = true,
    238    .lower_ifind_msb = true,
    239    .lower_isign = true,
    240    .lower_ldexp = true,
    241    .lower_mul_high = true,
    242    .lower_wpos_pntc = true,
    243    .lower_rotate = true,
    244    .lower_to_scalar = true,
    245    .lower_device_index_to_zero = true,
    246    .has_fsub = true,
    247    .has_isub = true,
    248    .vertex_id_zero_based = false, /* FIXME: to set this to true, the intrinsic
    249                                    * needs to be supported */
    250    .lower_interpolate_at = true,
    251    .max_unroll_iterations = 16,
    252    .force_indirect_unrolling = (nir_var_shader_in | nir_var_function_temp),
    253    .divergence_analysis_options =
    254       nir_divergence_multiple_workgroup_per_compute_subgroup
    255 };
    256 
    257 const nir_shader_compiler_options *
    258 v3dv_pipeline_get_nir_options(void)
    259 {
    260    return &v3dv_nir_options;
    261 }
    262 
    263 #define OPT(pass, ...) ({                                  \
    264    bool this_progress = false;                             \
    265    NIR_PASS(this_progress, nir, pass, ##__VA_ARGS__);      \
    266    if (this_progress)                                      \
    267       progress = true;                                     \
    268    this_progress;                                          \
    269 })
    270 
    271 static void
    272 nir_optimize(nir_shader *nir, bool allow_copies)
    273 {
    274    bool progress;
    275 
    276    do {
    277       progress = false;
    278       OPT(nir_split_array_vars, nir_var_function_temp);
    279       OPT(nir_shrink_vec_array_vars, nir_var_function_temp);
    280       OPT(nir_opt_deref);
    281       OPT(nir_lower_vars_to_ssa);
    282       if (allow_copies) {
    283          /* Only run this pass in the first call to nir_optimize.  Later calls
    284           * assume that we've lowered away any copy_deref instructions and we
    285           * don't want to introduce any more.
    286           */
    287          OPT(nir_opt_find_array_copies);
    288       }
    289       OPT(nir_opt_copy_prop_vars);
    290       OPT(nir_opt_dead_write_vars);
    291       OPT(nir_opt_combine_stores, nir_var_all);
    292 
    293       OPT(nir_lower_alu_to_scalar, NULL, NULL);
    294 
    295       OPT(nir_copy_prop);
    296       OPT(nir_lower_phis_to_scalar, false);
    297 
    298       OPT(nir_copy_prop);
    299       OPT(nir_opt_dce);
    300       OPT(nir_opt_cse);
    301       OPT(nir_opt_combine_stores, nir_var_all);
    302 
    303       /* Passing 0 to the peephole select pass causes it to convert
    304        * if-statements that contain only move instructions in the branches
    305        * regardless of the count.
    306        *
    307        * Passing 1 to the peephole select pass causes it to convert
    308        * if-statements that contain at most a single ALU instruction (total)
    309        * in both branches.
    310        */
    311       OPT(nir_opt_peephole_select, 0, false, false);
    312       OPT(nir_opt_peephole_select, 8, false, true);
    313 
    314       OPT(nir_opt_intrinsics);
    315       OPT(nir_opt_idiv_const, 32);
    316       OPT(nir_opt_algebraic);
    317       OPT(nir_opt_constant_folding);
    318 
    319       OPT(nir_opt_dead_cf);
    320 
    321       OPT(nir_opt_if, false);
    322       OPT(nir_opt_conditional_discard);
    323 
    324       OPT(nir_opt_remove_phis);
    325       OPT(nir_opt_undef);
    326       OPT(nir_lower_pack);
    327    } while (progress);
    328 
    329    OPT(nir_remove_dead_variables, nir_var_function_temp, NULL);
    330 }
    331 
    332 static void
    333 preprocess_nir(nir_shader *nir)
    334 {
    335    /* We have to lower away local variable initializers right before we
    336     * inline functions.  That way they get properly initialized at the top
    337     * of the function and not at the top of its caller.
    338     */
    339    NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
    340    NIR_PASS_V(nir, nir_lower_returns);
    341    NIR_PASS_V(nir, nir_inline_functions);
    342    NIR_PASS_V(nir, nir_opt_deref);
    343 
    344    /* Pick off the single entrypoint that we want */
    345    foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
    346       if (func->is_entrypoint)
    347          func->name = ralloc_strdup(func, "main");
    348       else
    349          exec_node_remove(&func->node);
    350    }
    351    assert(exec_list_length(&nir->functions) == 1);
    352 
    353    /* Vulkan uses the separate-shader linking model */
    354    nir->info.separate_shader = true;
    355 
    356    /* Make sure we lower variable initializers on output variables so that
    357     * nir_remove_dead_variables below sees the corresponding stores
    358     */
    359    NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_shader_out);
    360 
    361    /* Now that we've deleted all but the main function, we can go ahead and
    362     * lower the rest of the variable initializers.
    363     */
    364    NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
    365 
    366    /* Split member structs.  We do this before lower_io_to_temporaries so that
    367     * it doesn't lower system values to temporaries by accident.
    368     */
    369    NIR_PASS_V(nir, nir_split_var_copies);
    370    NIR_PASS_V(nir, nir_split_per_member_structs);
    371 
    372    if (nir->info.stage == MESA_SHADER_FRAGMENT)
    373       NIR_PASS_V(nir, nir_lower_io_to_vector, nir_var_shader_out);
    374    if (nir->info.stage == MESA_SHADER_FRAGMENT) {
    375       NIR_PASS_V(nir, nir_lower_input_attachments,
    376                  &(nir_input_attachment_options) {
    377                     .use_fragcoord_sysval = false,
    378                        });
    379    }
    380 
    381    NIR_PASS_V(nir, nir_lower_explicit_io,
    382               nir_var_mem_push_const,
    383               nir_address_format_32bit_offset);
    384 
    385    NIR_PASS_V(nir, nir_lower_explicit_io,
    386               nir_var_mem_ubo | nir_var_mem_ssbo,
    387               nir_address_format_32bit_index_offset);
    388 
    389    NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_in |
    390               nir_var_shader_out | nir_var_system_value | nir_var_mem_shared,
    391               NULL);
    392 
    393    NIR_PASS_V(nir, nir_propagate_invariant, false);
    394    NIR_PASS_V(nir, nir_lower_io_to_temporaries,
    395               nir_shader_get_entrypoint(nir), true, false);
    396 
    397    NIR_PASS_V(nir, nir_lower_system_values);
    398    NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
    399 
    400    NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
    401 
    402    NIR_PASS_V(nir, nir_normalize_cubemap_coords);
    403 
    404    NIR_PASS_V(nir, nir_lower_global_vars_to_local);
    405 
    406    NIR_PASS_V(nir, nir_split_var_copies);
    407    NIR_PASS_V(nir, nir_split_struct_vars, nir_var_function_temp);
    408 
    409    nir_optimize(nir, true);
    410 
    411    NIR_PASS_V(nir, nir_lower_load_const_to_scalar);
    412 
    413    /* Lower a bunch of stuff */
    414    NIR_PASS_V(nir, nir_lower_var_copies);
    415 
    416    NIR_PASS_V(nir, nir_lower_indirect_derefs, nir_var_shader_in, UINT32_MAX);
    417 
    418    NIR_PASS_V(nir, nir_lower_indirect_derefs,
    419               nir_var_function_temp, 2);
    420 
    421    NIR_PASS_V(nir, nir_lower_array_deref_of_vec,
    422               nir_var_mem_ubo | nir_var_mem_ssbo,
    423               nir_lower_direct_array_deref_of_vec_load);
    424 
    425    NIR_PASS_V(nir, nir_lower_frexp);
    426 
    427    /* Get rid of split copies */
    428    nir_optimize(nir, false);
    429 }
    430 
    431 static nir_shader *
    432 shader_module_compile_to_nir(struct v3dv_device *device,
    433                              struct v3dv_pipeline_stage *stage)
    434 {
    435    nir_shader *nir;
    436    const nir_shader_compiler_options *nir_options = &v3dv_nir_options;
    437 
    438    if (!stage->module->nir) {
    439       uint32_t *spirv = (uint32_t *) stage->module->data;
    440       assert(stage->module->size % 4 == 0);
    441 
    442       if (unlikely(V3D_DEBUG & V3D_DEBUG_DUMP_SPIRV))
    443          v3dv_print_spirv(stage->module->data, stage->module->size, stderr);
    444 
    445       uint32_t num_spec_entries = 0;
    446       struct nir_spirv_specialization *spec_entries =
    447          vk_spec_info_to_nir_spirv(stage->spec_info, &num_spec_entries);
    448       const struct spirv_to_nir_options spirv_options = default_spirv_options;
    449       nir = spirv_to_nir(spirv, stage->module->size / 4,
    450                          spec_entries, num_spec_entries,
    451                          broadcom_shader_stage_to_gl(stage->stage),
    452                          stage->entrypoint,
    453                          &spirv_options, nir_options);
    454       assert(nir);
    455       nir_validate_shader(nir, "after spirv_to_nir");
    456       free(spec_entries);
    457    } else {
    458       /* For NIR modules created by the driver we can't consume the NIR
    459        * directly, we need to clone it first, since ownership of the NIR code
    460        * (as with SPIR-V code for SPIR-V shaders), belongs to the creator
    461        * of the module and modules can be destroyed immediately after been used
    462        * to create pipelines.
    463        */
    464       nir = nir_shader_clone(NULL, stage->module->nir);
    465       nir_validate_shader(nir, "nir module");
    466    }
    467    assert(nir->info.stage == broadcom_shader_stage_to_gl(stage->stage));
    468 
    469    const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
    470       .frag_coord = true,
    471       .point_coord = true,
    472    };
    473    NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
    474 
    475    if (unlikely(V3D_DEBUG & (V3D_DEBUG_NIR |
    476                              v3d_debug_flag_for_shader_stage(
    477                                 broadcom_shader_stage_to_gl(stage->stage))))) {
    478       fprintf(stderr, "Initial form: %s prog %d NIR:\n",
    479               broadcom_shader_stage_name(stage->stage),
    480               stage->program_id);
    481       nir_print_shader(nir, stderr);
    482       fprintf(stderr, "\n");
    483    }
    484 
    485    preprocess_nir(nir);
    486 
    487    return nir;
    488 }
    489 
    490 static int
    491 type_size_vec4(const struct glsl_type *type, bool bindless)
    492 {
    493    return glsl_count_attribute_slots(type, false);
    494 }
    495 
    496 /* FIXME: the number of parameters for this method is somewhat big. Perhaps
    497  * rethink.
    498  */
    499 static unsigned
    500 descriptor_map_add(struct v3dv_descriptor_map *map,
    501                    int set,
    502                    int binding,
    503                    int array_index,
    504                    int array_size,
    505                    uint8_t return_size)
    506 {
    507    assert(array_index < array_size);
    508    assert(return_size == 16 || return_size == 32);
    509 
    510    unsigned index = 0;
    511    for (unsigned i = 0; i < map->num_desc; i++) {
    512       if (set == map->set[i] &&
    513           binding == map->binding[i] &&
    514           array_index == map->array_index[i]) {
    515          assert(array_size == map->array_size[i]);
    516          if (return_size != map->return_size[index]) {
    517             /* It the return_size is different it means that the same sampler
    518              * was used for operations with different precision
    519              * requirement. In this case we need to ensure that we use the
    520              * larger one.
    521              */
    522             map->return_size[index] = 32;
    523          }
    524          return index;
    525       }
    526       index++;
    527    }
    528 
    529    assert(index == map->num_desc);
    530 
    531    map->set[map->num_desc] = set;
    532    map->binding[map->num_desc] = binding;
    533    map->array_index[map->num_desc] = array_index;
    534    map->array_size[map->num_desc] = array_size;
    535    map->return_size[map->num_desc] = return_size;
    536    map->num_desc++;
    537 
    538    return index;
    539 }
    540 
    541 
    542 static void
    543 lower_load_push_constant(nir_builder *b, nir_intrinsic_instr *instr,
    544                          struct v3dv_pipeline *pipeline)
    545 {
    546    assert(instr->intrinsic == nir_intrinsic_load_push_constant);
    547    instr->intrinsic = nir_intrinsic_load_uniform;
    548 }
    549 
    550 static struct v3dv_descriptor_map*
    551 pipeline_get_descriptor_map(struct v3dv_pipeline *pipeline,
    552                             VkDescriptorType desc_type,
    553                             gl_shader_stage gl_stage,
    554                             bool is_sampler)
    555 {
    556    enum broadcom_shader_stage broadcom_stage =
    557       gl_shader_stage_to_broadcom(gl_stage);
    558 
    559    assert(pipeline->shared_data &&
    560           pipeline->shared_data->maps[broadcom_stage]);
    561 
    562    switch(desc_type) {
    563    case VK_DESCRIPTOR_TYPE_SAMPLER:
    564       return &pipeline->shared_data->maps[broadcom_stage]->sampler_map;
    565    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    566    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    567    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    568    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    569    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    570       return &pipeline->shared_data->maps[broadcom_stage]->texture_map;
    571    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    572       return is_sampler ?
    573          &pipeline->shared_data->maps[broadcom_stage]->sampler_map :
    574          &pipeline->shared_data->maps[broadcom_stage]->texture_map;
    575    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    576       return &pipeline->shared_data->maps[broadcom_stage]->ubo_map;
    577    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    578       return &pipeline->shared_data->maps[broadcom_stage]->ssbo_map;
    579    default:
    580       unreachable("Descriptor type unknown or not having a descriptor map");
    581    }
    582 }
    583 
    584 /* Gathers info from the intrinsic (set and binding) and then lowers it so it
    585  * could be used by the v3d_compiler */
    586 static void
    587 lower_vulkan_resource_index(nir_builder *b,
    588                             nir_intrinsic_instr *instr,
    589                             nir_shader *shader,
    590                             struct v3dv_pipeline *pipeline,
    591                             const struct v3dv_pipeline_layout *layout)
    592 {
    593    assert(instr->intrinsic == nir_intrinsic_vulkan_resource_index);
    594 
    595    nir_const_value *const_val = nir_src_as_const_value(instr->src[0]);
    596 
    597    unsigned set = nir_intrinsic_desc_set(instr);
    598    unsigned binding = nir_intrinsic_binding(instr);
    599    struct v3dv_descriptor_set_layout *set_layout = layout->set[set].layout;
    600    struct v3dv_descriptor_set_binding_layout *binding_layout =
    601       &set_layout->binding[binding];
    602    unsigned index = 0;
    603    const VkDescriptorType desc_type = nir_intrinsic_desc_type(instr);
    604 
    605    switch (desc_type) {
    606    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    607    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
    608       struct v3dv_descriptor_map *descriptor_map =
    609          pipeline_get_descriptor_map(pipeline, desc_type, shader->info.stage, false);
    610 
    611       if (!const_val)
    612          unreachable("non-constant vulkan_resource_index array index");
    613 
    614       index = descriptor_map_add(descriptor_map, set, binding,
    615                                  const_val->u32,
    616                                  binding_layout->array_size,
    617                                  32 /* return_size: doesn't really apply for this case */);
    618 
    619       if (desc_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
    620          /* skip index 0 which is used for push constants */
    621          index++;
    622       }
    623       break;
    624    }
    625 
    626    default:
    627       unreachable("unsupported desc_type for vulkan_resource_index");
    628       break;
    629    }
    630 
    631    /* Since we use the deref pass, both vulkan_resource_index and
    632     * vulkan_load_descriptor return a vec2 providing an index and
    633     * offset. Our backend compiler only cares about the index part.
    634     */
    635    nir_ssa_def_rewrite_uses(&instr->dest.ssa,
    636                             nir_imm_ivec2(b, index, 0));
    637    nir_instr_remove(&instr->instr);
    638 }
    639 
    640 /* Returns return_size, so it could be used for the case of not having a
    641  * sampler object
    642  */
    643 static uint8_t
    644 lower_tex_src_to_offset(nir_builder *b, nir_tex_instr *instr, unsigned src_idx,
    645                         nir_shader *shader,
    646                         struct v3dv_pipeline *pipeline,
    647                         const struct v3dv_pipeline_layout *layout)
    648 {
    649    nir_ssa_def *index = NULL;
    650    unsigned base_index = 0;
    651    unsigned array_elements = 1;
    652    nir_tex_src *src = &instr->src[src_idx];
    653    bool is_sampler = src->src_type == nir_tex_src_sampler_deref;
    654 
    655    /* We compute first the offsets */
    656    nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr);
    657    while (deref->deref_type != nir_deref_type_var) {
    658       assert(deref->parent.is_ssa);
    659       nir_deref_instr *parent =
    660          nir_instr_as_deref(deref->parent.ssa->parent_instr);
    661 
    662       assert(deref->deref_type == nir_deref_type_array);
    663 
    664       if (nir_src_is_const(deref->arr.index) && index == NULL) {
    665          /* We're still building a direct index */
    666          base_index += nir_src_as_uint(deref->arr.index) * array_elements;
    667       } else {
    668          if (index == NULL) {
    669             /* We used to be direct but not anymore */
    670             index = nir_imm_int(b, base_index);
    671             base_index = 0;
    672          }
    673 
    674          index = nir_iadd(b, index,
    675                           nir_imul(b, nir_imm_int(b, array_elements),
    676                                    nir_ssa_for_src(b, deref->arr.index, 1)));
    677       }
    678 
    679       array_elements *= glsl_get_length(parent->type);
    680 
    681       deref = parent;
    682    }
    683 
    684    if (index)
    685       index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
    686 
    687    /* We have the offsets, we apply them, rewriting the source or removing
    688     * instr if needed
    689     */
    690    if (index) {
    691       nir_instr_rewrite_src(&instr->instr, &src->src,
    692                             nir_src_for_ssa(index));
    693 
    694       src->src_type = is_sampler ?
    695          nir_tex_src_sampler_offset :
    696          nir_tex_src_texture_offset;
    697    } else {
    698       nir_tex_instr_remove_src(instr, src_idx);
    699    }
    700 
    701    uint32_t set = deref->var->data.descriptor_set;
    702    uint32_t binding = deref->var->data.binding;
    703    /* FIXME: this is a really simplified check for the precision to be used
    704     * for the sampling. Right now we are ony checking for the variables used
    705     * on the operation itself, but there are other cases that we could use to
    706     * infer the precision requirement.
    707     */
    708    bool relaxed_precision = deref->var->data.precision == GLSL_PRECISION_MEDIUM ||
    709                             deref->var->data.precision == GLSL_PRECISION_LOW;
    710    struct v3dv_descriptor_set_layout *set_layout = layout->set[set].layout;
    711    struct v3dv_descriptor_set_binding_layout *binding_layout =
    712       &set_layout->binding[binding];
    713 
    714    /* For input attachments, the shader includes the attachment_idx. As we are
    715     * treating them as a texture, we only want the base_index
    716     */
    717    uint32_t array_index = binding_layout->type != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ?
    718       deref->var->data.index + base_index :
    719       base_index;
    720 
    721    uint8_t return_size;
    722    if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_16BIT))
    723       return_size = 16;
    724    else  if (unlikely(V3D_DEBUG & V3D_DEBUG_TMU_32BIT))
    725       return_size = 32;
    726    else
    727       return_size = relaxed_precision || instr->is_shadow ? 16 : 32;
    728 
    729    struct v3dv_descriptor_map *map =
    730       pipeline_get_descriptor_map(pipeline, binding_layout->type,
    731                                   shader->info.stage, is_sampler);
    732    int desc_index =
    733       descriptor_map_add(map,
    734                          deref->var->data.descriptor_set,
    735                          deref->var->data.binding,
    736                          array_index,
    737                          binding_layout->array_size,
    738                          return_size);
    739 
    740    if (is_sampler)
    741       instr->sampler_index = desc_index;
    742    else
    743       instr->texture_index = desc_index;
    744 
    745    return return_size;
    746 }
    747 
    748 static bool
    749 lower_sampler(nir_builder *b, nir_tex_instr *instr,
    750               nir_shader *shader,
    751               struct v3dv_pipeline *pipeline,
    752               const struct v3dv_pipeline_layout *layout)
    753 {
    754    uint8_t return_size = 0;
    755 
    756    int texture_idx =
    757       nir_tex_instr_src_index(instr, nir_tex_src_texture_deref);
    758 
    759    if (texture_idx >= 0)
    760       return_size = lower_tex_src_to_offset(b, instr, texture_idx, shader,
    761                                             pipeline, layout);
    762 
    763    int sampler_idx =
    764       nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
    765 
    766    if (sampler_idx >= 0)
    767       lower_tex_src_to_offset(b, instr, sampler_idx, shader, pipeline, layout);
    768 
    769    if (texture_idx < 0 && sampler_idx < 0)
    770       return false;
    771 
    772    /* If we don't have a sampler, we assign it the idx we reserve for this
    773     * case, and we ensure that it is using the correct return size.
    774     */
    775    if (sampler_idx < 0) {
    776       instr->sampler_index = return_size == 16 ?
    777          V3DV_NO_SAMPLER_16BIT_IDX : V3DV_NO_SAMPLER_32BIT_IDX;
    778    }
    779 
    780    return true;
    781 }
    782 
    783 /* FIXME: really similar to lower_tex_src_to_offset, perhaps refactor? */
    784 static void
    785 lower_image_deref(nir_builder *b,
    786                   nir_intrinsic_instr *instr,
    787                   nir_shader *shader,
    788                   struct v3dv_pipeline *pipeline,
    789                   const struct v3dv_pipeline_layout *layout)
    790 {
    791    nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
    792    nir_ssa_def *index = NULL;
    793    unsigned array_elements = 1;
    794    unsigned base_index = 0;
    795 
    796    while (deref->deref_type != nir_deref_type_var) {
    797       assert(deref->parent.is_ssa);
    798       nir_deref_instr *parent =
    799          nir_instr_as_deref(deref->parent.ssa->parent_instr);
    800 
    801       assert(deref->deref_type == nir_deref_type_array);
    802 
    803       if (nir_src_is_const(deref->arr.index) && index == NULL) {
    804          /* We're still building a direct index */
    805          base_index += nir_src_as_uint(deref->arr.index) * array_elements;
    806       } else {
    807          if (index == NULL) {
    808             /* We used to be direct but not anymore */
    809             index = nir_imm_int(b, base_index);
    810             base_index = 0;
    811          }
    812 
    813          index = nir_iadd(b, index,
    814                           nir_imul(b, nir_imm_int(b, array_elements),
    815                                    nir_ssa_for_src(b, deref->arr.index, 1)));
    816       }
    817 
    818       array_elements *= glsl_get_length(parent->type);
    819 
    820       deref = parent;
    821    }
    822 
    823    if (index)
    824       index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
    825 
    826    uint32_t set = deref->var->data.descriptor_set;
    827    uint32_t binding = deref->var->data.binding;
    828    struct v3dv_descriptor_set_layout *set_layout = layout->set[set].layout;
    829    struct v3dv_descriptor_set_binding_layout *binding_layout =
    830       &set_layout->binding[binding];
    831 
    832    uint32_t array_index = deref->var->data.index + base_index;
    833 
    834    assert(binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
    835           binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
    836 
    837    struct v3dv_descriptor_map *map =
    838       pipeline_get_descriptor_map(pipeline, binding_layout->type,
    839                                   shader->info.stage, false);
    840 
    841    int desc_index =
    842       descriptor_map_add(map,
    843                          deref->var->data.descriptor_set,
    844                          deref->var->data.binding,
    845                          array_index,
    846                          binding_layout->array_size,
    847                          32 /* return_size: doesn't apply for textures */);
    848 
    849    /* Note: we don't need to do anything here in relation to the precision and
    850     * the output size because for images we can infer that info from the image
    851     * intrinsic, that includes the image format (see
    852     * NIR_INTRINSIC_FORMAT). That is done by the v3d compiler.
    853     */
    854 
    855    index = nir_imm_int(b, desc_index);
    856 
    857    nir_rewrite_image_intrinsic(instr, index, false);
    858 }
    859 
    860 static bool
    861 lower_intrinsic(nir_builder *b, nir_intrinsic_instr *instr,
    862                 nir_shader *shader,
    863                 struct v3dv_pipeline *pipeline,
    864                 const struct v3dv_pipeline_layout *layout)
    865 {
    866    switch (instr->intrinsic) {
    867    case nir_intrinsic_load_layer_id:
    868       /* FIXME: if layered rendering gets supported, this would need a real
    869        * lowering
    870        */
    871       nir_ssa_def_rewrite_uses(&instr->dest.ssa,
    872                                nir_imm_int(b, 0));
    873       nir_instr_remove(&instr->instr);
    874       return true;
    875 
    876    case nir_intrinsic_load_push_constant:
    877       lower_load_push_constant(b, instr, pipeline);
    878       return true;
    879 
    880    case nir_intrinsic_vulkan_resource_index:
    881       lower_vulkan_resource_index(b, instr, shader, pipeline, layout);
    882       return true;
    883 
    884    case nir_intrinsic_load_vulkan_descriptor: {
    885       /* Loading the descriptor happens as part of load/store instructions,
    886        * so for us this is a no-op.
    887        */
    888       nir_ssa_def_rewrite_uses(&instr->dest.ssa, instr->src[0].ssa);
    889       nir_instr_remove(&instr->instr);
    890       return true;
    891    }
    892 
    893    case nir_intrinsic_image_deref_load:
    894    case nir_intrinsic_image_deref_store:
    895    case nir_intrinsic_image_deref_atomic_add:
    896    case nir_intrinsic_image_deref_atomic_imin:
    897    case nir_intrinsic_image_deref_atomic_umin:
    898    case nir_intrinsic_image_deref_atomic_imax:
    899    case nir_intrinsic_image_deref_atomic_umax:
    900    case nir_intrinsic_image_deref_atomic_and:
    901    case nir_intrinsic_image_deref_atomic_or:
    902    case nir_intrinsic_image_deref_atomic_xor:
    903    case nir_intrinsic_image_deref_atomic_exchange:
    904    case nir_intrinsic_image_deref_atomic_comp_swap:
    905    case nir_intrinsic_image_deref_size:
    906    case nir_intrinsic_image_deref_samples:
    907       lower_image_deref(b, instr, shader, pipeline, layout);
    908       return true;
    909 
    910    default:
    911       return false;
    912    }
    913 }
    914 
    915 static bool
    916 lower_impl(nir_function_impl *impl,
    917            nir_shader *shader,
    918            struct v3dv_pipeline *pipeline,
    919            const struct v3dv_pipeline_layout *layout)
    920 {
    921    nir_builder b;
    922    nir_builder_init(&b, impl);
    923    bool progress = false;
    924 
    925    nir_foreach_block(block, impl) {
    926       nir_foreach_instr_safe(instr, block) {
    927          b.cursor = nir_before_instr(instr);
    928          switch (instr->type) {
    929          case nir_instr_type_tex:
    930             progress |=
    931                lower_sampler(&b, nir_instr_as_tex(instr), shader, pipeline, layout);
    932             break;
    933          case nir_instr_type_intrinsic:
    934             progress |=
    935                lower_intrinsic(&b, nir_instr_as_intrinsic(instr), shader,
    936                                pipeline, layout);
    937             break;
    938          default:
    939             break;
    940          }
    941       }
    942    }
    943 
    944    return progress;
    945 }
    946 
    947 static bool
    948 lower_pipeline_layout_info(nir_shader *shader,
    949                            struct v3dv_pipeline *pipeline,
    950                            const struct v3dv_pipeline_layout *layout)
    951 {
    952    bool progress = false;
    953 
    954    nir_foreach_function(function, shader) {
    955       if (function->impl)
    956          progress |= lower_impl(function->impl, shader, pipeline, layout);
    957    }
    958 
    959    return progress;
    960 }
    961 
    962 
    963 static void
    964 lower_fs_io(nir_shader *nir)
    965 {
    966    /* Our backend doesn't handle array fragment shader outputs */
    967    NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
    968    NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_out, NULL);
    969 
    970    nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
    971                                MESA_SHADER_FRAGMENT);
    972 
    973    nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
    974                                MESA_SHADER_FRAGMENT);
    975 
    976    NIR_PASS_V(nir, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
    977               type_size_vec4, 0);
    978 }
    979 
    980 static void
    981 lower_gs_io(struct nir_shader *nir)
    982 {
    983    NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
    984 
    985    nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
    986                                MESA_SHADER_GEOMETRY);
    987 
    988    nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
    989                                MESA_SHADER_GEOMETRY);
    990 }
    991 
    992 static void
    993 lower_vs_io(struct nir_shader *nir)
    994 {
    995    NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
    996 
    997    nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
    998                                MESA_SHADER_VERTEX);
    999 
   1000    nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
   1001                                MESA_SHADER_VERTEX);
   1002 
   1003    /* FIXME: if we call nir_lower_io, we get a crash later. Likely because it
   1004     * overlaps with v3d_nir_lower_io. Need further research though.
   1005     */
   1006 }
   1007 
   1008 static void
   1009 shader_debug_output(const char *message, void *data)
   1010 {
   1011    /* FIXME: We probably don't want to debug anything extra here, and in fact
   1012     * the compiler is not using this callback too much, only as an alternative
   1013     * way to debug out the shaderdb stats, that you can already get using
   1014     * V3D_DEBUG=shaderdb. Perhaps it would make sense to revisit the v3d
   1015     * compiler to remove that callback.
   1016     */
   1017 }
   1018 
   1019 static void
   1020 pipeline_populate_v3d_key(struct v3d_key *key,
   1021                           const struct v3dv_pipeline_stage *p_stage,
   1022                           uint32_t ucp_enables,
   1023                           bool robust_buffer_access)
   1024 {
   1025    assert(p_stage->pipeline->shared_data &&
   1026           p_stage->pipeline->shared_data->maps[p_stage->stage]);
   1027 
   1028    /* The following values are default values used at pipeline create. We use
   1029     * there 32 bit as default return size.
   1030     */
   1031    struct v3dv_descriptor_map *sampler_map =
   1032       &p_stage->pipeline->shared_data->maps[p_stage->stage]->sampler_map;
   1033    struct v3dv_descriptor_map *texture_map =
   1034       &p_stage->pipeline->shared_data->maps[p_stage->stage]->texture_map;
   1035 
   1036    key->num_tex_used = texture_map->num_desc;
   1037    assert(key->num_tex_used <= V3D_MAX_TEXTURE_SAMPLERS);
   1038    for (uint32_t tex_idx = 0; tex_idx < texture_map->num_desc; tex_idx++) {
   1039       key->tex[tex_idx].swizzle[0] = PIPE_SWIZZLE_X;
   1040       key->tex[tex_idx].swizzle[1] = PIPE_SWIZZLE_Y;
   1041       key->tex[tex_idx].swizzle[2] = PIPE_SWIZZLE_Z;
   1042       key->tex[tex_idx].swizzle[3] = PIPE_SWIZZLE_W;
   1043    }
   1044 
   1045    key->num_samplers_used = sampler_map->num_desc;
   1046    assert(key->num_samplers_used <= V3D_MAX_TEXTURE_SAMPLERS);
   1047    for (uint32_t sampler_idx = 0; sampler_idx < sampler_map->num_desc;
   1048         sampler_idx++) {
   1049       key->sampler[sampler_idx].return_size =
   1050          sampler_map->return_size[sampler_idx];
   1051 
   1052       key->sampler[sampler_idx].return_channels =
   1053          key->sampler[sampler_idx].return_size == 32 ? 4 : 2;
   1054    }
   1055 
   1056    switch (p_stage->stage) {
   1057    case BROADCOM_SHADER_VERTEX:
   1058    case BROADCOM_SHADER_VERTEX_BIN:
   1059       key->is_last_geometry_stage = p_stage->pipeline->gs == NULL;
   1060       break;
   1061    case BROADCOM_SHADER_GEOMETRY:
   1062    case BROADCOM_SHADER_GEOMETRY_BIN:
   1063       /* FIXME: while we don't implement tessellation shaders */
   1064       key->is_last_geometry_stage = true;
   1065       break;
   1066    case BROADCOM_SHADER_FRAGMENT:
   1067    case BROADCOM_SHADER_COMPUTE:
   1068       key->is_last_geometry_stage = false;
   1069       break;
   1070    default:
   1071       unreachable("unsupported shader stage");
   1072    }
   1073 
   1074    /* Vulkan doesn't have fixed function state for user clip planes. Instead,
   1075     * shaders can write to gl_ClipDistance[], in which case the SPIR-V compiler
   1076     * takes care of adding a single compact array variable at
   1077     * VARYING_SLOT_CLIP_DIST0, so we don't need any user clip plane lowering.
   1078     *
   1079     * The only lowering we are interested is specific to the fragment shader,
   1080     * where we want to emit discards to honor writes to gl_ClipDistance[] in
   1081     * previous stages. This is done via nir_lower_clip_fs() so we only set up
   1082     * the ucp enable mask for that stage.
   1083     */
   1084    key->ucp_enables = ucp_enables;
   1085 
   1086    key->robust_buffer_access = robust_buffer_access;
   1087 
   1088    key->environment = V3D_ENVIRONMENT_VULKAN;
   1089 }
   1090 
   1091 /* FIXME: anv maps to hw primitive type. Perhaps eventually we would do the
   1092  * same. For not using prim_mode that is the one already used on v3d
   1093  */
   1094 static const enum pipe_prim_type vk_to_pipe_prim_type[] = {
   1095    [VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = PIPE_PRIM_POINTS,
   1096    [VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = PIPE_PRIM_LINES,
   1097    [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = PIPE_PRIM_LINE_STRIP,
   1098    [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = PIPE_PRIM_TRIANGLES,
   1099    [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = PIPE_PRIM_TRIANGLE_STRIP,
   1100    [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = PIPE_PRIM_TRIANGLE_FAN,
   1101    [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = PIPE_PRIM_LINES_ADJACENCY,
   1102    [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = PIPE_PRIM_LINE_STRIP_ADJACENCY,
   1103    [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = PIPE_PRIM_TRIANGLES_ADJACENCY,
   1104    [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY,
   1105 };
   1106 
   1107 static const enum pipe_logicop vk_to_pipe_logicop[] = {
   1108    [VK_LOGIC_OP_CLEAR] = PIPE_LOGICOP_CLEAR,
   1109    [VK_LOGIC_OP_AND] = PIPE_LOGICOP_AND,
   1110    [VK_LOGIC_OP_AND_REVERSE] = PIPE_LOGICOP_AND_REVERSE,
   1111    [VK_LOGIC_OP_COPY] = PIPE_LOGICOP_COPY,
   1112    [VK_LOGIC_OP_AND_INVERTED] = PIPE_LOGICOP_AND_INVERTED,
   1113    [VK_LOGIC_OP_NO_OP] = PIPE_LOGICOP_NOOP,
   1114    [VK_LOGIC_OP_XOR] = PIPE_LOGICOP_XOR,
   1115    [VK_LOGIC_OP_OR] = PIPE_LOGICOP_OR,
   1116    [VK_LOGIC_OP_NOR] = PIPE_LOGICOP_NOR,
   1117    [VK_LOGIC_OP_EQUIVALENT] = PIPE_LOGICOP_EQUIV,
   1118    [VK_LOGIC_OP_INVERT] = PIPE_LOGICOP_INVERT,
   1119    [VK_LOGIC_OP_OR_REVERSE] = PIPE_LOGICOP_OR_REVERSE,
   1120    [VK_LOGIC_OP_COPY_INVERTED] = PIPE_LOGICOP_COPY_INVERTED,
   1121    [VK_LOGIC_OP_OR_INVERTED] = PIPE_LOGICOP_OR_INVERTED,
   1122    [VK_LOGIC_OP_NAND] = PIPE_LOGICOP_NAND,
   1123    [VK_LOGIC_OP_SET] = PIPE_LOGICOP_SET,
   1124 };
   1125 
   1126 static void
   1127 pipeline_populate_v3d_fs_key(struct v3d_fs_key *key,
   1128                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
   1129                              const struct v3dv_pipeline_stage *p_stage,
   1130                              bool has_geometry_shader,
   1131                              uint32_t ucp_enables)
   1132 {
   1133    assert(p_stage->stage == BROADCOM_SHADER_FRAGMENT);
   1134 
   1135    memset(key, 0, sizeof(*key));
   1136 
   1137    const bool rba = p_stage->pipeline->device->features.robustBufferAccess;
   1138    pipeline_populate_v3d_key(&key->base, p_stage, ucp_enables, rba);
   1139 
   1140    const VkPipelineInputAssemblyStateCreateInfo *ia_info =
   1141       pCreateInfo->pInputAssemblyState;
   1142    uint8_t topology = vk_to_pipe_prim_type[ia_info->topology];
   1143 
   1144    key->is_points = (topology == PIPE_PRIM_POINTS);
   1145    key->is_lines = (topology >= PIPE_PRIM_LINES &&
   1146                     topology <= PIPE_PRIM_LINE_STRIP);
   1147    key->has_gs = has_geometry_shader;
   1148 
   1149    const VkPipelineColorBlendStateCreateInfo *cb_info =
   1150       !pCreateInfo->pRasterizationState->rasterizerDiscardEnable ?
   1151       pCreateInfo->pColorBlendState : NULL;
   1152 
   1153    key->logicop_func = cb_info && cb_info->logicOpEnable == VK_TRUE ?
   1154                        vk_to_pipe_logicop[cb_info->logicOp] :
   1155                        PIPE_LOGICOP_COPY;
   1156 
   1157    const bool raster_enabled =
   1158       !pCreateInfo->pRasterizationState->rasterizerDiscardEnable;
   1159 
   1160    /* Multisample rasterization state must be ignored if rasterization
   1161     * is disabled.
   1162     */
   1163    const VkPipelineMultisampleStateCreateInfo *ms_info =
   1164       raster_enabled ? pCreateInfo->pMultisampleState : NULL;
   1165    if (ms_info) {
   1166       assert(ms_info->rasterizationSamples == VK_SAMPLE_COUNT_1_BIT ||
   1167              ms_info->rasterizationSamples == VK_SAMPLE_COUNT_4_BIT);
   1168       key->msaa = ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT;
   1169 
   1170       if (key->msaa) {
   1171          key->sample_coverage =
   1172             p_stage->pipeline->sample_mask != (1 << V3D_MAX_SAMPLES) - 1;
   1173          key->sample_alpha_to_coverage = ms_info->alphaToCoverageEnable;
   1174          key->sample_alpha_to_one = ms_info->alphaToOneEnable;
   1175       }
   1176    }
   1177 
   1178    /* This is intended for V3D versions before 4.1, otherwise we just use the
   1179     * tile buffer load/store swap R/B bit.
   1180     */
   1181    key->swap_color_rb = 0;
   1182 
   1183    const struct v3dv_render_pass *pass =
   1184       v3dv_render_pass_from_handle(pCreateInfo->renderPass);
   1185    const struct v3dv_subpass *subpass = p_stage->pipeline->subpass;
   1186    for (uint32_t i = 0; i < subpass->color_count; i++) {
   1187       const uint32_t att_idx = subpass->color_attachments[i].attachment;
   1188       if (att_idx == VK_ATTACHMENT_UNUSED)
   1189          continue;
   1190 
   1191       key->cbufs |= 1 << i;
   1192 
   1193       VkFormat fb_format = pass->attachments[att_idx].desc.format;
   1194       enum pipe_format fb_pipe_format = vk_format_to_pipe_format(fb_format);
   1195 
   1196       /* If logic operations are enabled then we might emit color reads and we
   1197        * need to know the color buffer format and swizzle for that
   1198        */
   1199       if (key->logicop_func != PIPE_LOGICOP_COPY) {
   1200          key->color_fmt[i].format = fb_pipe_format;
   1201          key->color_fmt[i].swizzle =
   1202             v3dv_get_format_swizzle(p_stage->pipeline->device, fb_format);
   1203       }
   1204 
   1205       const struct util_format_description *desc =
   1206          vk_format_description(fb_format);
   1207 
   1208       if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT &&
   1209           desc->channel[0].size == 32) {
   1210          key->f32_color_rb |= 1 << i;
   1211       }
   1212 
   1213       if (p_stage->nir->info.fs.untyped_color_outputs) {
   1214          if (util_format_is_pure_uint(fb_pipe_format))
   1215             key->uint_color_rb |= 1 << i;
   1216          else if (util_format_is_pure_sint(fb_pipe_format))
   1217             key->int_color_rb |= 1 << i;
   1218       }
   1219 
   1220       if (key->is_points) {
   1221          /* FIXME: The mask would need to be computed based on the shader
   1222           * inputs. On gallium it is done at st_atom_rasterizer
   1223           * (sprite_coord_enable). anv seems (need to confirm) to do that on
   1224           * genX_pipeline (PointSpriteTextureCoordinateEnable). Would be also
   1225           * better to have tests to guide filling the mask.
   1226           */
   1227          key->point_sprite_mask = 0;
   1228 
   1229          /* Vulkan mandates upper left. */
   1230          key->point_coord_upper_left = true;
   1231       }
   1232    }
   1233 }
   1234 
   1235 static void
   1236 setup_stage_outputs_from_next_stage_inputs(
   1237    uint8_t next_stage_num_inputs,
   1238    struct v3d_varying_slot *next_stage_input_slots,
   1239    uint8_t *num_used_outputs,
   1240    struct v3d_varying_slot *used_output_slots,
   1241    uint32_t size_of_used_output_slots)
   1242 {
   1243    *num_used_outputs = next_stage_num_inputs;
   1244    memcpy(used_output_slots, next_stage_input_slots, size_of_used_output_slots);
   1245 }
   1246 
   1247 static void
   1248 pipeline_populate_v3d_gs_key(struct v3d_gs_key *key,
   1249                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
   1250                              const struct v3dv_pipeline_stage *p_stage)
   1251 {
   1252    assert(p_stage->stage == BROADCOM_SHADER_GEOMETRY ||
   1253           p_stage->stage == BROADCOM_SHADER_GEOMETRY_BIN);
   1254 
   1255    memset(key, 0, sizeof(*key));
   1256 
   1257    const bool rba = p_stage->pipeline->device->features.robustBufferAccess;
   1258    pipeline_populate_v3d_key(&key->base, p_stage, 0, rba);
   1259 
   1260    struct v3dv_pipeline *pipeline = p_stage->pipeline;
   1261 
   1262    key->per_vertex_point_size =
   1263       p_stage->nir->info.outputs_written & (1ull << VARYING_SLOT_PSIZ);
   1264 
   1265    key->is_coord = broadcom_shader_stage_is_binning(p_stage->stage);
   1266 
   1267    assert(key->base.is_last_geometry_stage);
   1268    if (key->is_coord) {
   1269       /* Output varyings in the last binning shader are only used for transform
   1270        * feedback. Set to 0 as VK_EXT_transform_feedback is not supported.
   1271        */
   1272       key->num_used_outputs = 0;
   1273    } else {
   1274       struct v3dv_shader_variant *fs_variant =
   1275          pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
   1276 
   1277       STATIC_ASSERT(sizeof(key->used_outputs) ==
   1278                     sizeof(fs_variant->prog_data.fs->input_slots));
   1279 
   1280       setup_stage_outputs_from_next_stage_inputs(
   1281          fs_variant->prog_data.fs->num_inputs,
   1282          fs_variant->prog_data.fs->input_slots,
   1283          &key->num_used_outputs,
   1284          key->used_outputs,
   1285          sizeof(key->used_outputs));
   1286    }
   1287 }
   1288 
   1289 static void
   1290 pipeline_populate_v3d_vs_key(struct v3d_vs_key *key,
   1291                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
   1292                              const struct v3dv_pipeline_stage *p_stage)
   1293 {
   1294    assert(p_stage->stage == BROADCOM_SHADER_VERTEX ||
   1295           p_stage->stage == BROADCOM_SHADER_VERTEX_BIN);
   1296 
   1297    memset(key, 0, sizeof(*key));
   1298 
   1299    const bool rba = p_stage->pipeline->device->features.robustBufferAccess;
   1300    pipeline_populate_v3d_key(&key->base, p_stage, 0, rba);
   1301 
   1302    struct v3dv_pipeline *pipeline = p_stage->pipeline;
   1303 
   1304    /* Vulkan specifies a point size per vertex, so true for if the prim are
   1305     * points, like on ES2)
   1306     */
   1307    const VkPipelineInputAssemblyStateCreateInfo *ia_info =
   1308       pCreateInfo->pInputAssemblyState;
   1309    uint8_t topology = vk_to_pipe_prim_type[ia_info->topology];
   1310 
   1311    /* FIXME: PRIM_POINTS is not enough, in gallium the full check is
   1312     * PIPE_PRIM_POINTS && v3d->rasterizer->base.point_size_per_vertex */
   1313    key->per_vertex_point_size = (topology == PIPE_PRIM_POINTS);
   1314 
   1315    key->is_coord = broadcom_shader_stage_is_binning(p_stage->stage);
   1316 
   1317    if (key->is_coord) { /* Binning VS*/
   1318       if (key->base.is_last_geometry_stage) {
   1319          /* Output varyings in the last binning shader are only used for
   1320           * transform feedback. Set to 0 as VK_EXT_transform_feedback is not
   1321           * supported.
   1322           */
   1323          key->num_used_outputs = 0;
   1324       } else {
   1325          /* Linking against GS binning program */
   1326          assert(pipeline->gs);
   1327          struct v3dv_shader_variant *gs_bin_variant =
   1328             pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN];
   1329 
   1330          STATIC_ASSERT(sizeof(key->used_outputs) ==
   1331                        sizeof(gs_bin_variant->prog_data.gs->input_slots));
   1332 
   1333          setup_stage_outputs_from_next_stage_inputs(
   1334             gs_bin_variant->prog_data.gs->num_inputs,
   1335             gs_bin_variant->prog_data.gs->input_slots,
   1336             &key->num_used_outputs,
   1337             key->used_outputs,
   1338             sizeof(key->used_outputs));
   1339       }
   1340    } else { /* Render VS */
   1341       if (pipeline->gs) {
   1342          /* Linking against GS render program */
   1343          struct v3dv_shader_variant *gs_variant =
   1344             pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY];
   1345 
   1346          STATIC_ASSERT(sizeof(key->used_outputs) ==
   1347                        sizeof(gs_variant->prog_data.gs->input_slots));
   1348 
   1349          setup_stage_outputs_from_next_stage_inputs(
   1350             gs_variant->prog_data.gs->num_inputs,
   1351             gs_variant->prog_data.gs->input_slots,
   1352             &key->num_used_outputs,
   1353             key->used_outputs,
   1354             sizeof(key->used_outputs));
   1355       } else {
   1356          /* Linking against FS program */
   1357          struct v3dv_shader_variant *fs_variant =
   1358             pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
   1359 
   1360          STATIC_ASSERT(sizeof(key->used_outputs) ==
   1361                        sizeof(fs_variant->prog_data.fs->input_slots));
   1362 
   1363          setup_stage_outputs_from_next_stage_inputs(
   1364             fs_variant->prog_data.fs->num_inputs,
   1365             fs_variant->prog_data.fs->input_slots,
   1366             &key->num_used_outputs,
   1367             key->used_outputs,
   1368             sizeof(key->used_outputs));
   1369       }
   1370    }
   1371 
   1372    const VkPipelineVertexInputStateCreateInfo *vi_info =
   1373       pCreateInfo->pVertexInputState;
   1374    for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
   1375       const VkVertexInputAttributeDescription *desc =
   1376          &vi_info->pVertexAttributeDescriptions[i];
   1377       assert(desc->location < MAX_VERTEX_ATTRIBS);
   1378       if (desc->format == VK_FORMAT_B8G8R8A8_UNORM)
   1379          key->va_swap_rb_mask |= 1 << (VERT_ATTRIB_GENERIC0 + desc->location);
   1380    }
   1381 }
   1382 
   1383 /**
   1384  * Creates the initial form of the pipeline stage for a binning shader by
   1385  * cloning the render shader and flagging it as a coordinate shader.
   1386  *
   1387  * Returns NULL if it was not able to allocate the object, so it should be
   1388  * handled as a VK_ERROR_OUT_OF_HOST_MEMORY error.
   1389  */
   1390 static struct v3dv_pipeline_stage *
   1391 pipeline_stage_create_binning(const struct v3dv_pipeline_stage *src,
   1392                               const VkAllocationCallbacks *pAllocator)
   1393 {
   1394    struct v3dv_device *device = src->pipeline->device;
   1395 
   1396    struct v3dv_pipeline_stage *p_stage =
   1397       vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
   1398                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   1399 
   1400    if (p_stage == NULL)
   1401       return NULL;
   1402 
   1403    assert(src->stage == BROADCOM_SHADER_VERTEX ||
   1404           src->stage == BROADCOM_SHADER_GEOMETRY);
   1405 
   1406    enum broadcom_shader_stage bin_stage =
   1407       src->stage == BROADCOM_SHADER_VERTEX ?
   1408          BROADCOM_SHADER_VERTEX_BIN :
   1409          BROADCOM_SHADER_GEOMETRY_BIN;
   1410 
   1411    p_stage->pipeline = src->pipeline;
   1412    p_stage->stage = bin_stage;
   1413    p_stage->entrypoint = src->entrypoint;
   1414    p_stage->module = src->module;
   1415    /* For binning shaders we will clone the NIR code from the corresponding
   1416     * render shader later, when we call pipeline_compile_xxx_shader. This way
   1417     * we only have to run the relevant NIR lowerings once for render shaders
   1418     */
   1419    p_stage->nir = NULL;
   1420    p_stage->spec_info = src->spec_info;
   1421    p_stage->feedback = (VkPipelineCreationFeedbackEXT) { 0 };
   1422    memcpy(p_stage->shader_sha1, src->shader_sha1, 20);
   1423 
   1424    return p_stage;
   1425 }
   1426 
   1427 /**
   1428  * Returns false if it was not able to allocate or map the assembly bo memory.
   1429  */
   1430 static bool
   1431 upload_assembly(struct v3dv_pipeline *pipeline)
   1432 {
   1433    uint32_t total_size = 0;
   1434    for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
   1435       struct v3dv_shader_variant *variant =
   1436          pipeline->shared_data->variants[stage];
   1437 
   1438       if (variant != NULL)
   1439          total_size += variant->qpu_insts_size;
   1440    }
   1441 
   1442    struct v3dv_bo *bo = v3dv_bo_alloc(pipeline->device, total_size,
   1443                                       "pipeline shader assembly", true);
   1444    if (!bo) {
   1445       fprintf(stderr, "failed to allocate memory for shader\n");
   1446       return false;
   1447    }
   1448 
   1449    bool ok = v3dv_bo_map(pipeline->device, bo, total_size);
   1450    if (!ok) {
   1451       fprintf(stderr, "failed to map source shader buffer\n");
   1452       return false;
   1453    }
   1454 
   1455    uint32_t offset = 0;
   1456    for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
   1457       struct v3dv_shader_variant *variant =
   1458          pipeline->shared_data->variants[stage];
   1459 
   1460       if (variant != NULL) {
   1461          variant->assembly_offset = offset;
   1462 
   1463          memcpy(bo->map + offset, variant->qpu_insts, variant->qpu_insts_size);
   1464          offset += variant->qpu_insts_size;
   1465 
   1466          /* We dont need qpu_insts anymore. */
   1467          free(variant->qpu_insts);
   1468          variant->qpu_insts = NULL;
   1469       }
   1470    }
   1471    assert(total_size == offset);
   1472 
   1473    pipeline->shared_data->assembly_bo = bo;
   1474 
   1475    return true;
   1476 }
   1477 
   1478 static void
   1479 pipeline_hash_graphics(const struct v3dv_pipeline *pipeline,
   1480                        struct v3dv_pipeline_key *key,
   1481                        unsigned char *sha1_out)
   1482 {
   1483    struct mesa_sha1 ctx;
   1484    _mesa_sha1_init(&ctx);
   1485 
   1486    /* We need to include all shader stages in the sha1 key as linking may modify
   1487     * the shader code in any stage. An alternative would be to use the
   1488     * serialized NIR, but that seems like an overkill.
   1489     */
   1490    _mesa_sha1_update(&ctx, pipeline->vs->shader_sha1,
   1491                      sizeof(pipeline->vs->shader_sha1));
   1492 
   1493    if (pipeline->gs) {
   1494       _mesa_sha1_update(&ctx, pipeline->gs->shader_sha1,
   1495                         sizeof(pipeline->gs->shader_sha1));
   1496    }
   1497 
   1498    _mesa_sha1_update(&ctx, pipeline->fs->shader_sha1,
   1499                      sizeof(pipeline->fs->shader_sha1));
   1500 
   1501    _mesa_sha1_update(&ctx, key, sizeof(struct v3dv_pipeline_key));
   1502 
   1503    _mesa_sha1_final(&ctx, sha1_out);
   1504 }
   1505 
   1506 static void
   1507 pipeline_hash_compute(const struct v3dv_pipeline *pipeline,
   1508                       struct v3dv_pipeline_key *key,
   1509                       unsigned char *sha1_out)
   1510 {
   1511    struct mesa_sha1 ctx;
   1512    _mesa_sha1_init(&ctx);
   1513 
   1514    _mesa_sha1_update(&ctx, pipeline->cs->shader_sha1,
   1515                      sizeof(pipeline->cs->shader_sha1));
   1516 
   1517    _mesa_sha1_update(&ctx, key, sizeof(struct v3dv_pipeline_key));
   1518 
   1519    _mesa_sha1_final(&ctx, sha1_out);
   1520 }
   1521 
   1522 /* Checks that the pipeline has enough spill size to use for any of their
   1523  * variants
   1524  */
   1525 static void
   1526 pipeline_check_spill_size(struct v3dv_pipeline *pipeline)
   1527 {
   1528    uint32_t max_spill_size = 0;
   1529 
   1530    for(uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
   1531       struct v3dv_shader_variant *variant =
   1532          pipeline->shared_data->variants[stage];
   1533 
   1534       if (variant != NULL) {
   1535          max_spill_size = MAX2(variant->prog_data.base->spill_size,
   1536                                max_spill_size);
   1537       }
   1538    }
   1539 
   1540    if (max_spill_size > 0) {
   1541       struct v3dv_device *device = pipeline->device;
   1542 
   1543       /* The TIDX register we use for choosing the area to access
   1544        * for scratch space is: (core << 6) | (qpu << 2) | thread.
   1545        * Even at minimum threadcount in a particular shader, that
   1546        * means we still multiply by qpus by 4.
   1547        */
   1548       const uint32_t total_spill_size =
   1549          4 * device->devinfo.qpu_count * max_spill_size;
   1550       if (pipeline->spill.bo) {
   1551          assert(pipeline->spill.size_per_thread > 0);
   1552          v3dv_bo_free(device, pipeline->spill.bo);
   1553       }
   1554       pipeline->spill.bo =
   1555          v3dv_bo_alloc(device, total_spill_size, "spill", true);
   1556       pipeline->spill.size_per_thread = max_spill_size;
   1557    }
   1558 }
   1559 
   1560 /**
   1561  * Creates a new shader_variant_create. Note that for prog_data is not const,
   1562  * so it is assumed that the caller will prove a pointer that the
   1563  * shader_variant will own.
   1564  *
   1565  * Creation doesn't include allocate a BD to store the content of qpu_insts,
   1566  * as we will try to share the same bo for several shader variants. Also note
   1567  * that qpu_ints being NULL is valid, for example if we are creating the
   1568  * shader_variants from the cache, so we can just upload the assembly of all
   1569  * the shader stages at once.
   1570  */
   1571 struct v3dv_shader_variant *
   1572 v3dv_shader_variant_create(struct v3dv_device *device,
   1573                            enum broadcom_shader_stage stage,
   1574                            struct v3d_prog_data *prog_data,
   1575                            uint32_t prog_data_size,
   1576                            uint32_t assembly_offset,
   1577                            uint64_t *qpu_insts,
   1578                            uint32_t qpu_insts_size,
   1579                            VkResult *out_vk_result)
   1580 {
   1581    struct v3dv_shader_variant *variant =
   1582       vk_zalloc(&device->vk.alloc, sizeof(*variant), 8,
   1583                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   1584 
   1585    if (variant == NULL) {
   1586       *out_vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
   1587       return NULL;
   1588    }
   1589 
   1590    variant->stage = stage;
   1591    variant->prog_data_size = prog_data_size;
   1592    variant->prog_data.base = prog_data;
   1593 
   1594    variant->assembly_offset = assembly_offset;
   1595    variant->qpu_insts_size = qpu_insts_size;
   1596    variant->qpu_insts = qpu_insts;
   1597 
   1598    *out_vk_result = VK_SUCCESS;
   1599 
   1600    return variant;
   1601 }
   1602 
   1603 /* For a given key, it returns the compiled version of the shader.  Returns a
   1604  * new reference to the shader_variant to the caller, or NULL.
   1605  *
   1606  * If the method returns NULL it means that something wrong happened:
   1607  *   * Not enough memory: this is one of the possible outcomes defined by
   1608  *     vkCreateXXXPipelines. out_vk_result will return the proper oom error.
   1609  *   * Compilation error: hypothetically this shouldn't happen, as the spec
   1610  *     states that vkShaderModule needs to be created with a valid SPIR-V, so
   1611  *     any compilation failure is a driver bug. In the practice, something as
   1612  *     common as failing to register allocate can lead to a compilation
   1613  *     failure. In that case the only option (for any driver) is
   1614  *     VK_ERROR_UNKNOWN, even if we know that the problem was a compiler
   1615  *     error.
   1616  */
   1617 static struct v3dv_shader_variant *
   1618 pipeline_compile_shader_variant(struct v3dv_pipeline_stage *p_stage,
   1619                                 struct v3d_key *key,
   1620                                 size_t key_size,
   1621                                 const VkAllocationCallbacks *pAllocator,
   1622                                 VkResult *out_vk_result)
   1623 {
   1624    int64_t stage_start = os_time_get_nano();
   1625 
   1626    struct v3dv_pipeline *pipeline = p_stage->pipeline;
   1627    struct v3dv_physical_device *physical_device =
   1628       &pipeline->device->instance->physicalDevice;
   1629    const struct v3d_compiler *compiler = physical_device->compiler;
   1630 
   1631    if (unlikely(V3D_DEBUG & (V3D_DEBUG_NIR |
   1632                              v3d_debug_flag_for_shader_stage
   1633                              (broadcom_shader_stage_to_gl(p_stage->stage))))) {
   1634       fprintf(stderr, "Just before v3d_compile: %s prog %d NIR:\n",
   1635               broadcom_shader_stage_name(p_stage->stage),
   1636               p_stage->program_id);
   1637       nir_print_shader(p_stage->nir, stderr);
   1638       fprintf(stderr, "\n");
   1639    }
   1640 
   1641    uint64_t *qpu_insts;
   1642    uint32_t qpu_insts_size;
   1643    struct v3d_prog_data *prog_data;
   1644    uint32_t prog_data_size =
   1645       v3d_prog_data_size(broadcom_shader_stage_to_gl(p_stage->stage));
   1646 
   1647    qpu_insts = v3d_compile(compiler,
   1648                            key, &prog_data,
   1649                            p_stage->nir,
   1650                            shader_debug_output, NULL,
   1651                            p_stage->program_id, 0,
   1652                            &qpu_insts_size);
   1653 
   1654    struct v3dv_shader_variant *variant = NULL;
   1655 
   1656    if (!qpu_insts) {
   1657       fprintf(stderr, "Failed to compile %s prog %d NIR to VIR\n",
   1658               gl_shader_stage_name(p_stage->stage),
   1659               p_stage->program_id);
   1660       *out_vk_result = VK_ERROR_UNKNOWN;
   1661    } else {
   1662       variant =
   1663          v3dv_shader_variant_create(pipeline->device, p_stage->stage,
   1664                                     prog_data, prog_data_size,
   1665                                     0, /* assembly_offset, no final value yet */
   1666                                     qpu_insts, qpu_insts_size,
   1667                                     out_vk_result);
   1668    }
   1669    /* At this point we don't need anymore the nir shader, but we are freeing
   1670     * all the temporary p_stage structs used during the pipeline creation when
   1671     * we finish it, so let's not worry about freeing the nir here.
   1672     */
   1673 
   1674    p_stage->feedback.duration += os_time_get_nano() - stage_start;
   1675 
   1676    return variant;
   1677 }
   1678 
   1679 /* FIXME: C&P from st, common place? */
   1680 static void
   1681 st_nir_opts(nir_shader *nir)
   1682 {
   1683    bool progress;
   1684 
   1685    do {
   1686       progress = false;
   1687 
   1688       NIR_PASS_V(nir, nir_lower_vars_to_ssa);
   1689 
   1690       /* Linking deals with unused inputs/outputs, but here we can remove
   1691        * things local to the shader in the hopes that we can cleanup other
   1692        * things. This pass will also remove variables with only stores, so we
   1693        * might be able to make progress after it.
   1694        */
   1695       NIR_PASS(progress, nir, nir_remove_dead_variables,
   1696                (nir_variable_mode)(nir_var_function_temp |
   1697                                    nir_var_shader_temp |
   1698                                    nir_var_mem_shared),
   1699                NULL);
   1700 
   1701       NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
   1702       NIR_PASS(progress, nir, nir_opt_dead_write_vars);
   1703 
   1704       if (nir->options->lower_to_scalar) {
   1705          NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
   1706          NIR_PASS_V(nir, nir_lower_phis_to_scalar, false);
   1707       }
   1708 
   1709       NIR_PASS_V(nir, nir_lower_alu);
   1710       NIR_PASS_V(nir, nir_lower_pack);
   1711       NIR_PASS(progress, nir, nir_copy_prop);
   1712       NIR_PASS(progress, nir, nir_opt_remove_phis);
   1713       NIR_PASS(progress, nir, nir_opt_dce);
   1714       if (nir_opt_trivial_continues(nir)) {
   1715          progress = true;
   1716          NIR_PASS(progress, nir, nir_copy_prop);
   1717          NIR_PASS(progress, nir, nir_opt_dce);
   1718       }
   1719       NIR_PASS(progress, nir, nir_opt_if, false);
   1720       NIR_PASS(progress, nir, nir_opt_dead_cf);
   1721       NIR_PASS(progress, nir, nir_opt_cse);
   1722       NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
   1723 
   1724       NIR_PASS(progress, nir, nir_opt_algebraic);
   1725       NIR_PASS(progress, nir, nir_opt_constant_folding);
   1726 
   1727       NIR_PASS(progress, nir, nir_opt_undef);
   1728       NIR_PASS(progress, nir, nir_opt_conditional_discard);
   1729    } while (progress);
   1730 }
   1731 
   1732 static void
   1733 link_shaders(nir_shader *producer, nir_shader *consumer)
   1734 {
   1735    assert(producer);
   1736    assert(consumer);
   1737 
   1738    if (producer->options->lower_to_scalar) {
   1739       NIR_PASS_V(producer, nir_lower_io_to_scalar_early, nir_var_shader_out);
   1740       NIR_PASS_V(consumer, nir_lower_io_to_scalar_early, nir_var_shader_in);
   1741    }
   1742 
   1743    nir_lower_io_arrays_to_elements(producer, consumer);
   1744 
   1745    st_nir_opts(producer);
   1746    st_nir_opts(consumer);
   1747 
   1748    if (nir_link_opt_varyings(producer, consumer))
   1749       st_nir_opts(consumer);
   1750 
   1751    NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
   1752    NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
   1753 
   1754    if (nir_remove_unused_varyings(producer, consumer)) {
   1755       NIR_PASS_V(producer, nir_lower_global_vars_to_local);
   1756       NIR_PASS_V(consumer, nir_lower_global_vars_to_local);
   1757 
   1758       st_nir_opts(producer);
   1759       st_nir_opts(consumer);
   1760 
   1761       /* Optimizations can cause varyings to become unused.
   1762        * nir_compact_varyings() depends on all dead varyings being removed so
   1763        * we need to call nir_remove_dead_variables() again here.
   1764        */
   1765       NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
   1766       NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
   1767    }
   1768 }
   1769 
   1770 static void
   1771 pipeline_lower_nir(struct v3dv_pipeline *pipeline,
   1772                    struct v3dv_pipeline_stage *p_stage,
   1773                    struct v3dv_pipeline_layout *layout)
   1774 {
   1775    int64_t stage_start = os_time_get_nano();
   1776 
   1777    assert(pipeline->shared_data &&
   1778           pipeline->shared_data->maps[p_stage->stage]);
   1779 
   1780    nir_shader_gather_info(p_stage->nir, nir_shader_get_entrypoint(p_stage->nir));
   1781 
   1782    /* We add this because we need a valid sampler for nir_lower_tex to do
   1783     * unpacking of the texture operation result, even for the case where there
   1784     * is no sampler state.
   1785     *
   1786     * We add two of those, one for the case we need a 16bit return_size, and
   1787     * another for the case we need a 32bit return size.
   1788     */
   1789    UNUSED unsigned index =
   1790       descriptor_map_add(&pipeline->shared_data->maps[p_stage->stage]->sampler_map,
   1791                          -1, -1, -1, 0, 16);
   1792    assert(index == V3DV_NO_SAMPLER_16BIT_IDX);
   1793 
   1794    index =
   1795       descriptor_map_add(&pipeline->shared_data->maps[p_stage->stage]->sampler_map,
   1796                          -2, -2, -2, 0, 32);
   1797    assert(index == V3DV_NO_SAMPLER_32BIT_IDX);
   1798 
   1799    /* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
   1800    NIR_PASS_V(p_stage->nir, lower_pipeline_layout_info, pipeline, layout);
   1801 
   1802    p_stage->feedback.duration += os_time_get_nano() - stage_start;
   1803 }
   1804 
   1805 /**
   1806  * The SPIR-V compiler will insert a sized compact array for
   1807  * VARYING_SLOT_CLIP_DIST0 if the vertex shader writes to gl_ClipDistance[],
   1808  * where the size of the array determines the number of active clip planes.
   1809  */
   1810 static uint32_t
   1811 get_ucp_enable_mask(struct v3dv_pipeline_stage *p_stage)
   1812 {
   1813    assert(p_stage->stage == BROADCOM_SHADER_VERTEX);
   1814    const nir_shader *shader = p_stage->nir;
   1815    assert(shader);
   1816 
   1817    nir_foreach_variable_with_modes(var, shader, nir_var_shader_out) {
   1818       if (var->data.location == VARYING_SLOT_CLIP_DIST0) {
   1819          assert(var->data.compact);
   1820          return (1 << glsl_get_length(var->type)) - 1;
   1821       }
   1822    }
   1823    return 0;
   1824 }
   1825 
   1826 static nir_shader *
   1827 pipeline_stage_get_nir(struct v3dv_pipeline_stage *p_stage,
   1828                        struct v3dv_pipeline *pipeline,
   1829                        struct v3dv_pipeline_cache *cache)
   1830 {
   1831    int64_t stage_start = os_time_get_nano();
   1832 
   1833    nir_shader *nir = NULL;
   1834 
   1835    nir = v3dv_pipeline_cache_search_for_nir(pipeline, cache,
   1836                                             &v3dv_nir_options,
   1837                                             p_stage->shader_sha1);
   1838 
   1839    if (nir) {
   1840       assert(nir->info.stage == broadcom_shader_stage_to_gl(p_stage->stage));
   1841 
   1842       /* A NIR cach hit doesn't avoid the large majority of pipeline stage
   1843        * creation so the cache hit is not recorded in the pipeline feedback
   1844        * flags
   1845        */
   1846 
   1847       p_stage->feedback.duration += os_time_get_nano() - stage_start;
   1848 
   1849       return nir;
   1850    }
   1851 
   1852    nir = shader_module_compile_to_nir(pipeline->device, p_stage);
   1853 
   1854    if (nir) {
   1855       struct v3dv_pipeline_cache *default_cache =
   1856          &pipeline->device->default_pipeline_cache;
   1857 
   1858       v3dv_pipeline_cache_upload_nir(pipeline, cache, nir,
   1859                                      p_stage->shader_sha1);
   1860 
   1861       /* Ensure that the variant is on the default cache, as cmd_buffer could
   1862        * need to change the current variant
   1863        */
   1864       if (default_cache != cache) {
   1865          v3dv_pipeline_cache_upload_nir(pipeline, default_cache, nir,
   1866                                         p_stage->shader_sha1);
   1867       }
   1868 
   1869       p_stage->feedback.duration += os_time_get_nano() - stage_start;
   1870 
   1871       return nir;
   1872    }
   1873 
   1874    /* FIXME: this shouldn't happen, raise error? */
   1875    return NULL;
   1876 }
   1877 
   1878 static void
   1879 pipeline_hash_shader(const struct vk_shader_module *module,
   1880                      const char *entrypoint,
   1881                      gl_shader_stage stage,
   1882                      const VkSpecializationInfo *spec_info,
   1883                      unsigned char *sha1_out)
   1884 {
   1885    struct mesa_sha1 ctx;
   1886    _mesa_sha1_init(&ctx);
   1887 
   1888    _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
   1889    _mesa_sha1_update(&ctx, entrypoint, strlen(entrypoint));
   1890    _mesa_sha1_update(&ctx, &stage, sizeof(stage));
   1891    if (spec_info) {
   1892       _mesa_sha1_update(&ctx, spec_info->pMapEntries,
   1893                         spec_info->mapEntryCount *
   1894                         sizeof(*spec_info->pMapEntries));
   1895       _mesa_sha1_update(&ctx, spec_info->pData,
   1896                         spec_info->dataSize);
   1897    }
   1898 
   1899    _mesa_sha1_final(&ctx, sha1_out);
   1900 }
   1901 
   1902 static VkResult
   1903 pipeline_compile_vertex_shader(struct v3dv_pipeline *pipeline,
   1904                                const VkAllocationCallbacks *pAllocator,
   1905                                const VkGraphicsPipelineCreateInfo *pCreateInfo)
   1906 {
   1907    assert(pipeline->vs_bin != NULL);
   1908    if (pipeline->vs_bin->nir == NULL) {
   1909       assert(pipeline->vs->nir);
   1910       pipeline->vs_bin->nir = nir_shader_clone(NULL, pipeline->vs->nir);
   1911    }
   1912 
   1913    VkResult vk_result;
   1914    struct v3d_vs_key key;
   1915    pipeline_populate_v3d_vs_key(&key, pCreateInfo, pipeline->vs);
   1916    pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX] =
   1917       pipeline_compile_shader_variant(pipeline->vs, &key.base, sizeof(key),
   1918                                       pAllocator, &vk_result);
   1919    if (vk_result != VK_SUCCESS)
   1920       return vk_result;
   1921 
   1922    pipeline_populate_v3d_vs_key(&key, pCreateInfo, pipeline->vs_bin);
   1923    pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN] =
   1924       pipeline_compile_shader_variant(pipeline->vs_bin, &key.base, sizeof(key),
   1925                                       pAllocator, &vk_result);
   1926 
   1927    return vk_result;
   1928 }
   1929 
   1930 static VkResult
   1931 pipeline_compile_geometry_shader(struct v3dv_pipeline *pipeline,
   1932                                  const VkAllocationCallbacks *pAllocator,
   1933                                  const VkGraphicsPipelineCreateInfo *pCreateInfo)
   1934 {
   1935    assert(pipeline->gs);
   1936 
   1937    assert(pipeline->gs_bin != NULL);
   1938    if (pipeline->gs_bin->nir == NULL) {
   1939       assert(pipeline->gs->nir);
   1940       pipeline->gs_bin->nir = nir_shader_clone(NULL, pipeline->gs->nir);
   1941    }
   1942 
   1943    VkResult vk_result;
   1944    struct v3d_gs_key key;
   1945    pipeline_populate_v3d_gs_key(&key, pCreateInfo, pipeline->gs);
   1946    pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY] =
   1947       pipeline_compile_shader_variant(pipeline->gs, &key.base, sizeof(key),
   1948                                       pAllocator, &vk_result);
   1949    if (vk_result != VK_SUCCESS)
   1950       return vk_result;
   1951 
   1952    pipeline_populate_v3d_gs_key(&key, pCreateInfo, pipeline->gs_bin);
   1953    pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN] =
   1954       pipeline_compile_shader_variant(pipeline->gs_bin, &key.base, sizeof(key),
   1955                                       pAllocator, &vk_result);
   1956 
   1957    return vk_result;
   1958 }
   1959 
   1960 static VkResult
   1961 pipeline_compile_fragment_shader(struct v3dv_pipeline *pipeline,
   1962                                  const VkAllocationCallbacks *pAllocator,
   1963                                  const VkGraphicsPipelineCreateInfo *pCreateInfo)
   1964 {
   1965    struct v3dv_pipeline_stage *p_stage = pipeline->vs;
   1966 
   1967    p_stage = pipeline->fs;
   1968 
   1969    struct v3d_fs_key key;
   1970 
   1971    pipeline_populate_v3d_fs_key(&key, pCreateInfo, p_stage,
   1972                                 pipeline->gs != NULL,
   1973                                 get_ucp_enable_mask(pipeline->vs));
   1974 
   1975    VkResult vk_result;
   1976    pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT] =
   1977       pipeline_compile_shader_variant(p_stage, &key.base, sizeof(key),
   1978                                       pAllocator, &vk_result);
   1979 
   1980    return vk_result;
   1981 }
   1982 
   1983 static void
   1984 pipeline_populate_graphics_key(struct v3dv_pipeline *pipeline,
   1985                                struct v3dv_pipeline_key *key,
   1986                                const VkGraphicsPipelineCreateInfo *pCreateInfo)
   1987 {
   1988    memset(key, 0, sizeof(*key));
   1989    key->robust_buffer_access =
   1990       pipeline->device->features.robustBufferAccess;
   1991 
   1992    const bool raster_enabled =
   1993       !pCreateInfo->pRasterizationState->rasterizerDiscardEnable;
   1994 
   1995    const VkPipelineInputAssemblyStateCreateInfo *ia_info =
   1996       pCreateInfo->pInputAssemblyState;
   1997    key->topology = vk_to_pipe_prim_type[ia_info->topology];
   1998 
   1999    const VkPipelineColorBlendStateCreateInfo *cb_info =
   2000       raster_enabled ? pCreateInfo->pColorBlendState : NULL;
   2001 
   2002    key->logicop_func = cb_info && cb_info->logicOpEnable == VK_TRUE ?
   2003       vk_to_pipe_logicop[cb_info->logicOp] :
   2004       PIPE_LOGICOP_COPY;
   2005 
   2006    /* Multisample rasterization state must be ignored if rasterization
   2007     * is disabled.
   2008     */
   2009    const VkPipelineMultisampleStateCreateInfo *ms_info =
   2010       raster_enabled ? pCreateInfo->pMultisampleState : NULL;
   2011    if (ms_info) {
   2012       assert(ms_info->rasterizationSamples == VK_SAMPLE_COUNT_1_BIT ||
   2013              ms_info->rasterizationSamples == VK_SAMPLE_COUNT_4_BIT);
   2014       key->msaa = ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT;
   2015 
   2016       if (key->msaa) {
   2017          key->sample_coverage =
   2018             pipeline->sample_mask != (1 << V3D_MAX_SAMPLES) - 1;
   2019          key->sample_alpha_to_coverage = ms_info->alphaToCoverageEnable;
   2020          key->sample_alpha_to_one = ms_info->alphaToOneEnable;
   2021       }
   2022    }
   2023 
   2024    const struct v3dv_render_pass *pass =
   2025       v3dv_render_pass_from_handle(pCreateInfo->renderPass);
   2026    const struct v3dv_subpass *subpass = pipeline->subpass;
   2027    for (uint32_t i = 0; i < subpass->color_count; i++) {
   2028       const uint32_t att_idx = subpass->color_attachments[i].attachment;
   2029       if (att_idx == VK_ATTACHMENT_UNUSED)
   2030          continue;
   2031 
   2032       key->cbufs |= 1 << i;
   2033 
   2034       VkFormat fb_format = pass->attachments[att_idx].desc.format;
   2035       enum pipe_format fb_pipe_format = vk_format_to_pipe_format(fb_format);
   2036 
   2037       /* If logic operations are enabled then we might emit color reads and we
   2038        * need to know the color buffer format and swizzle for that
   2039        */
   2040       if (key->logicop_func != PIPE_LOGICOP_COPY) {
   2041          key->color_fmt[i].format = fb_pipe_format;
   2042          key->color_fmt[i].swizzle = v3dv_get_format_swizzle(pipeline->device,
   2043                                                              fb_format);
   2044       }
   2045 
   2046       const struct util_format_description *desc =
   2047          vk_format_description(fb_format);
   2048 
   2049       if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT &&
   2050           desc->channel[0].size == 32) {
   2051          key->f32_color_rb |= 1 << i;
   2052       }
   2053    }
   2054 
   2055    const VkPipelineVertexInputStateCreateInfo *vi_info =
   2056       pCreateInfo->pVertexInputState;
   2057    for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
   2058       const VkVertexInputAttributeDescription *desc =
   2059          &vi_info->pVertexAttributeDescriptions[i];
   2060       assert(desc->location < MAX_VERTEX_ATTRIBS);
   2061       if (desc->format == VK_FORMAT_B8G8R8A8_UNORM)
   2062          key->va_swap_rb_mask |= 1 << (VERT_ATTRIB_GENERIC0 + desc->location);
   2063    }
   2064 
   2065    assert(pipeline->subpass);
   2066    key->has_multiview = pipeline->subpass->view_mask != 0;
   2067 }
   2068 
   2069 static void
   2070 pipeline_populate_compute_key(struct v3dv_pipeline *pipeline,
   2071                               struct v3dv_pipeline_key *key,
   2072                               const VkComputePipelineCreateInfo *pCreateInfo)
   2073 {
   2074    /* We use the same pipeline key for graphics and compute, but we don't need
   2075     * to add a field to flag compute keys because this key is not used alone
   2076     * to search in the cache, we also use the SPIR-V or the serialized NIR for
   2077     * example, which already flags compute shaders.
   2078     */
   2079    memset(key, 0, sizeof(*key));
   2080    key->robust_buffer_access =
   2081       pipeline->device->features.robustBufferAccess;
   2082 }
   2083 
   2084 static struct v3dv_pipeline_shared_data *
   2085 v3dv_pipeline_shared_data_new_empty(const unsigned char sha1_key[20],
   2086                                     struct v3dv_pipeline *pipeline,
   2087                                     bool is_graphics_pipeline)
   2088 {
   2089    /* We create new_entry using the device alloc. Right now shared_data is ref
   2090     * and unref by both the pipeline and the pipeline cache, so we can't
   2091     * ensure that the cache or pipeline alloc will be available on the last
   2092     * unref.
   2093     */
   2094    struct v3dv_pipeline_shared_data *new_entry =
   2095       vk_zalloc2(&pipeline->device->vk.alloc, NULL,
   2096                  sizeof(struct v3dv_pipeline_shared_data), 8,
   2097                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   2098 
   2099    if (new_entry == NULL)
   2100       return NULL;
   2101 
   2102    for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
   2103       /* We don't need specific descriptor maps for binning stages we use the
   2104        * map for the render stage.
   2105        */
   2106       if (broadcom_shader_stage_is_binning(stage))
   2107          continue;
   2108 
   2109       if ((is_graphics_pipeline && stage == BROADCOM_SHADER_COMPUTE) ||
   2110           (!is_graphics_pipeline && stage != BROADCOM_SHADER_COMPUTE)) {
   2111          continue;
   2112       }
   2113 
   2114       if (stage == BROADCOM_SHADER_GEOMETRY && !pipeline->gs) {
   2115          /* We always inject a custom GS if we have multiview */
   2116          if (!pipeline->subpass->view_mask)
   2117             continue;
   2118       }
   2119 
   2120       struct v3dv_descriptor_maps *new_maps =
   2121          vk_zalloc2(&pipeline->device->vk.alloc, NULL,
   2122                     sizeof(struct v3dv_descriptor_maps), 8,
   2123                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   2124 
   2125       if (new_maps == NULL)
   2126          goto fail;
   2127 
   2128       new_entry->maps[stage] = new_maps;
   2129    }
   2130 
   2131    new_entry->maps[BROADCOM_SHADER_VERTEX_BIN] =
   2132       new_entry->maps[BROADCOM_SHADER_VERTEX];
   2133 
   2134    new_entry->maps[BROADCOM_SHADER_GEOMETRY_BIN] =
   2135       new_entry->maps[BROADCOM_SHADER_GEOMETRY];
   2136 
   2137    new_entry->ref_cnt = 1;
   2138    memcpy(new_entry->sha1_key, sha1_key, 20);
   2139 
   2140    return new_entry;
   2141 
   2142 fail:
   2143    if (new_entry != NULL) {
   2144       for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
   2145          if (new_entry->maps[stage] != NULL)
   2146             vk_free(&pipeline->device->vk.alloc, new_entry->maps[stage]);
   2147       }
   2148    }
   2149 
   2150    vk_free(&pipeline->device->vk.alloc, new_entry);
   2151 
   2152    return NULL;
   2153 }
   2154 
   2155 static void
   2156 write_creation_feedback(struct v3dv_pipeline *pipeline,
   2157                         const void *next,
   2158                         const VkPipelineCreationFeedbackEXT *pipeline_feedback,
   2159                         uint32_t stage_count,
   2160                         const VkPipelineShaderStageCreateInfo *stages)
   2161 {
   2162    const VkPipelineCreationFeedbackCreateInfoEXT *create_feedback =
   2163       vk_find_struct_const(next, PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT);
   2164 
   2165    if (create_feedback) {
   2166       typed_memcpy(create_feedback->pPipelineCreationFeedback,
   2167              pipeline_feedback,
   2168              1);
   2169 
   2170       assert(stage_count == create_feedback->pipelineStageCreationFeedbackCount);
   2171 
   2172       for (uint32_t i = 0; i < stage_count; i++) {
   2173          gl_shader_stage s = vk_to_mesa_shader_stage(stages[i].stage);
   2174          switch (s) {
   2175          case MESA_SHADER_VERTEX:
   2176             create_feedback->pPipelineStageCreationFeedbacks[i] =
   2177                pipeline->vs->feedback;
   2178 
   2179             create_feedback->pPipelineStageCreationFeedbacks[i].duration +=
   2180                pipeline->vs_bin->feedback.duration;
   2181             break;
   2182 
   2183          case MESA_SHADER_GEOMETRY:
   2184             create_feedback->pPipelineStageCreationFeedbacks[i] =
   2185                pipeline->gs->feedback;
   2186 
   2187             create_feedback->pPipelineStageCreationFeedbacks[i].duration +=
   2188                pipeline->gs_bin->feedback.duration;
   2189             break;
   2190 
   2191          case MESA_SHADER_FRAGMENT:
   2192             create_feedback->pPipelineStageCreationFeedbacks[i] =
   2193                pipeline->fs->feedback;
   2194             break;
   2195 
   2196          case MESA_SHADER_COMPUTE:
   2197             create_feedback->pPipelineStageCreationFeedbacks[i] =
   2198                pipeline->cs->feedback;
   2199             break;
   2200 
   2201          default:
   2202             unreachable("not supported shader stage");
   2203          }
   2204       }
   2205    }
   2206 }
   2207 
   2208 static uint32_t
   2209 multiview_gs_input_primitive_from_pipeline(struct v3dv_pipeline *pipeline)
   2210 {
   2211    switch (pipeline->topology) {
   2212    case PIPE_PRIM_POINTS:
   2213       return GL_POINTS;
   2214    case PIPE_PRIM_LINES:
   2215    case PIPE_PRIM_LINE_STRIP:
   2216       return GL_LINES;
   2217    case PIPE_PRIM_TRIANGLES:
   2218    case PIPE_PRIM_TRIANGLE_STRIP:
   2219    case PIPE_PRIM_TRIANGLE_FAN:
   2220       return GL_TRIANGLES;
   2221    default:
   2222       /* Since we don't allow GS with multiview, we can only see non-adjacency
   2223        * primitives.
   2224        */
   2225       unreachable("Unexpected pipeline primitive type");
   2226    }
   2227 }
   2228 
   2229 static uint32_t
   2230 multiview_gs_output_primitive_from_pipeline(struct v3dv_pipeline *pipeline)
   2231 {
   2232    switch (pipeline->topology) {
   2233    case PIPE_PRIM_POINTS:
   2234       return GL_POINTS;
   2235    case PIPE_PRIM_LINES:
   2236    case PIPE_PRIM_LINE_STRIP:
   2237       return GL_LINE_STRIP;
   2238    case PIPE_PRIM_TRIANGLES:
   2239    case PIPE_PRIM_TRIANGLE_STRIP:
   2240    case PIPE_PRIM_TRIANGLE_FAN:
   2241       return GL_TRIANGLE_STRIP;
   2242    default:
   2243       /* Since we don't allow GS with multiview, we can only see non-adjacency
   2244        * primitives.
   2245        */
   2246       unreachable("Unexpected pipeline primitive type");
   2247    }
   2248 }
   2249 
   2250 static bool
   2251 pipeline_add_multiview_gs(struct v3dv_pipeline *pipeline,
   2252                           struct v3dv_pipeline_cache *cache,
   2253                           const VkAllocationCallbacks *pAllocator)
   2254 {
   2255    /* Create the passthrough GS from the VS output interface */
   2256    pipeline->vs->nir = pipeline_stage_get_nir(pipeline->vs, pipeline, cache);
   2257    nir_shader *vs_nir = pipeline->vs->nir;
   2258 
   2259    const nir_shader_compiler_options *options = v3dv_pipeline_get_nir_options();
   2260    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY, options,
   2261                                                   "multiview broadcast gs");
   2262    nir_shader *nir = b.shader;
   2263    nir->info.inputs_read = vs_nir->info.outputs_written;
   2264    nir->info.outputs_written = vs_nir->info.outputs_written |
   2265                                (1ull << VARYING_SLOT_LAYER);
   2266 
   2267    uint32_t vertex_count = u_vertices_per_prim(pipeline->topology);
   2268    nir->info.gs.input_primitive =
   2269       multiview_gs_input_primitive_from_pipeline(pipeline);
   2270    nir->info.gs.output_primitive =
   2271       multiview_gs_output_primitive_from_pipeline(pipeline);
   2272    nir->info.gs.vertices_in = vertex_count;
   2273    nir->info.gs.vertices_out = nir->info.gs.vertices_in;
   2274    nir->info.gs.invocations = 1;
   2275    nir->info.gs.active_stream_mask = 0x1;
   2276 
   2277    /* Make a list of GS input/output variables from the VS outputs */
   2278    nir_variable *in_vars[100];
   2279    nir_variable *out_vars[100];
   2280    uint32_t var_count = 0;
   2281    nir_foreach_shader_out_variable(out_vs_var, vs_nir) {
   2282       char name[8];
   2283       snprintf(name, ARRAY_SIZE(name), "in_%d", var_count);
   2284 
   2285       in_vars[var_count] =
   2286          nir_variable_create(nir, nir_var_shader_in,
   2287                              glsl_array_type(out_vs_var->type, vertex_count, 0),
   2288                              name);
   2289       in_vars[var_count]->data.location = out_vs_var->data.location;
   2290       in_vars[var_count]->data.location_frac = out_vs_var->data.location_frac;
   2291       in_vars[var_count]->data.interpolation = out_vs_var->data.interpolation;
   2292 
   2293       snprintf(name, ARRAY_SIZE(name), "out_%d", var_count);
   2294       out_vars[var_count] =
   2295          nir_variable_create(nir, nir_var_shader_out, out_vs_var->type, name);
   2296       out_vars[var_count]->data.location = out_vs_var->data.location;
   2297       out_vars[var_count]->data.interpolation = out_vs_var->data.interpolation;
   2298 
   2299       var_count++;
   2300    }
   2301 
   2302    /* Add the gl_Layer output variable */
   2303    nir_variable *out_layer =
   2304       nir_variable_create(nir, nir_var_shader_out, glsl_int_type(),
   2305                           "out_Layer");
   2306    out_layer->data.location = VARYING_SLOT_LAYER;
   2307 
   2308    /* Get the view index value that we will write to gl_Layer */
   2309    nir_ssa_def *layer =
   2310       nir_load_system_value(&b, nir_intrinsic_load_view_index, 0, 1, 32);
   2311 
   2312    /* Emit all output vertices */
   2313    for (uint32_t vi = 0; vi < vertex_count; vi++) {
   2314       /* Emit all output varyings */
   2315       for (uint32_t i = 0; i < var_count; i++) {
   2316          nir_deref_instr *in_value =
   2317             nir_build_deref_array_imm(&b, nir_build_deref_var(&b, in_vars[i]), vi);
   2318          nir_copy_deref(&b, nir_build_deref_var(&b, out_vars[i]), in_value);
   2319       }
   2320 
   2321       /* Emit gl_Layer write */
   2322       nir_store_var(&b, out_layer, layer, 0x1);
   2323 
   2324       nir_emit_vertex(&b, 0);
   2325    }
   2326    nir_end_primitive(&b, 0);
   2327 
   2328    /* Make sure we run our pre-process NIR passes so we produce NIR compatible
   2329     * with what we expect from SPIR-V modules.
   2330     */
   2331    preprocess_nir(nir);
   2332 
   2333    /* Attach the geometry shader to the  pipeline */
   2334    struct v3dv_device *device = pipeline->device;
   2335    struct v3dv_physical_device *physical_device =
   2336       &device->instance->physicalDevice;
   2337 
   2338    struct v3dv_pipeline_stage *p_stage =
   2339       vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
   2340                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   2341 
   2342    if (p_stage == NULL) {
   2343       ralloc_free(nir);
   2344       return false;
   2345    }
   2346 
   2347    p_stage->pipeline = pipeline;
   2348    p_stage->stage = BROADCOM_SHADER_GEOMETRY;
   2349    p_stage->entrypoint = "main";
   2350    p_stage->module = 0;
   2351    p_stage->nir = nir;
   2352    pipeline_compute_sha1_from_nir(p_stage->nir, p_stage->shader_sha1);
   2353    p_stage->program_id = p_atomic_inc_return(&physical_device->next_program_id);
   2354 
   2355    pipeline->has_gs = true;
   2356    pipeline->gs = p_stage;
   2357    pipeline->active_stages |= MESA_SHADER_GEOMETRY;
   2358 
   2359    pipeline->gs_bin =
   2360       pipeline_stage_create_binning(pipeline->gs, pAllocator);
   2361       if (pipeline->gs_bin == NULL)
   2362          return false;
   2363 
   2364    return true;
   2365 }
   2366 
   2367 /*
   2368  * It compiles a pipeline. Note that it also allocate internal object, but if
   2369  * some allocations success, but other fails, the method is not freeing the
   2370  * successful ones.
   2371  *
   2372  * This is done to simplify the code, as what we do in this case is just call
   2373  * the pipeline destroy method, and this would handle freeing the internal
   2374  * objects allocated. We just need to be careful setting to NULL the objects
   2375  * not allocated.
   2376  */
   2377 static VkResult
   2378 pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
   2379                           struct v3dv_pipeline_cache *cache,
   2380                           const VkGraphicsPipelineCreateInfo *pCreateInfo,
   2381                           const VkAllocationCallbacks *pAllocator)
   2382 {
   2383    VkPipelineCreationFeedbackEXT pipeline_feedback = {
   2384       .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT,
   2385    };
   2386    int64_t pipeline_start = os_time_get_nano();
   2387 
   2388    struct v3dv_device *device = pipeline->device;
   2389    struct v3dv_physical_device *physical_device =
   2390       &device->instance->physicalDevice;
   2391 
   2392    /* First pass to get some common info from the shader, and create the
   2393     * individual pipeline_stage objects
   2394     */
   2395    for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
   2396       const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
   2397       gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
   2398 
   2399       struct v3dv_pipeline_stage *p_stage =
   2400          vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
   2401                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   2402 
   2403       if (p_stage == NULL)
   2404          return VK_ERROR_OUT_OF_HOST_MEMORY;
   2405 
   2406       /* Note that we are assigning program_id slightly differently that
   2407        * v3d. Here we are assigning one per pipeline stage, so vs and vs_bin
   2408        * would have a different program_id, while v3d would have the same for
   2409        * both. For the case of v3dv, it is more natural to have an id this way,
   2410        * as right now we are using it for debugging, not for shader-db.
   2411        */
   2412       p_stage->program_id =
   2413          p_atomic_inc_return(&physical_device->next_program_id);
   2414 
   2415       p_stage->pipeline = pipeline;
   2416       p_stage->stage = gl_shader_stage_to_broadcom(stage);
   2417       p_stage->entrypoint = sinfo->pName;
   2418       p_stage->module = vk_shader_module_from_handle(sinfo->module);
   2419       p_stage->spec_info = sinfo->pSpecializationInfo;
   2420 
   2421       pipeline_hash_shader(p_stage->module,
   2422                            p_stage->entrypoint,
   2423                            stage,
   2424                            p_stage->spec_info,
   2425                            p_stage->shader_sha1);
   2426 
   2427       pipeline->active_stages |= sinfo->stage;
   2428 
   2429       /* We will try to get directly the compiled shader variant, so let's not
   2430        * worry about getting the nir shader for now.
   2431        */
   2432       p_stage->nir = NULL;
   2433 
   2434       switch(stage) {
   2435       case MESA_SHADER_VERTEX:
   2436          pipeline->vs = p_stage;
   2437          pipeline->vs_bin =
   2438             pipeline_stage_create_binning(pipeline->vs, pAllocator);
   2439          if (pipeline->vs_bin == NULL)
   2440             return VK_ERROR_OUT_OF_HOST_MEMORY;
   2441          break;
   2442 
   2443       case MESA_SHADER_GEOMETRY:
   2444          pipeline->has_gs = true;
   2445          pipeline->gs = p_stage;
   2446          pipeline->gs_bin =
   2447             pipeline_stage_create_binning(pipeline->gs, pAllocator);
   2448          if (pipeline->gs_bin == NULL)
   2449             return VK_ERROR_OUT_OF_HOST_MEMORY;
   2450          break;
   2451 
   2452       case MESA_SHADER_FRAGMENT:
   2453          pipeline->fs = p_stage;
   2454          break;
   2455 
   2456       default:
   2457          unreachable("not supported shader stage");
   2458       }
   2459    }
   2460 
   2461    /* Add a no-op fragment shader if needed */
   2462    if (!pipeline->fs) {
   2463       nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
   2464                                                      &v3dv_nir_options,
   2465                                                      "noop_fs");
   2466 
   2467       struct v3dv_pipeline_stage *p_stage =
   2468          vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
   2469                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   2470 
   2471       if (p_stage == NULL)
   2472          return VK_ERROR_OUT_OF_HOST_MEMORY;
   2473 
   2474       p_stage->pipeline = pipeline;
   2475       p_stage->stage = BROADCOM_SHADER_FRAGMENT;
   2476       p_stage->entrypoint = "main";
   2477       p_stage->module = 0;
   2478       p_stage->nir = b.shader;
   2479       pipeline_compute_sha1_from_nir(p_stage->nir, p_stage->shader_sha1);
   2480       p_stage->program_id =
   2481          p_atomic_inc_return(&physical_device->next_program_id);
   2482 
   2483       pipeline->fs = p_stage;
   2484       pipeline->active_stages |= MESA_SHADER_FRAGMENT;
   2485    }
   2486 
   2487    /* If multiview is enabled, we inject a custom passthrough geometry shader
   2488     * to broadcast draw calls to the appropriate views.
   2489     */
   2490    assert(!pipeline->subpass->view_mask || (!pipeline->has_gs && !pipeline->gs));
   2491    if (pipeline->subpass->view_mask) {
   2492       if (!pipeline_add_multiview_gs(pipeline, cache, pAllocator))
   2493          return VK_ERROR_OUT_OF_HOST_MEMORY;
   2494    }
   2495 
   2496    /* First we try to get the variants from the pipeline cache */
   2497    struct v3dv_pipeline_key pipeline_key;
   2498    pipeline_populate_graphics_key(pipeline, &pipeline_key, pCreateInfo);
   2499    unsigned char pipeline_sha1[20];
   2500    pipeline_hash_graphics(pipeline, &pipeline_key, pipeline_sha1);
   2501 
   2502    bool cache_hit = false;
   2503 
   2504    pipeline->shared_data =
   2505       v3dv_pipeline_cache_search_for_pipeline(cache,
   2506                                               pipeline_sha1,
   2507                                               &cache_hit);
   2508 
   2509    if (pipeline->shared_data != NULL) {
   2510       /* A correct pipeline must have at least a VS and FS */
   2511       assert(pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]);
   2512       assert(pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]);
   2513       assert(pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]);
   2514       assert(!pipeline->gs ||
   2515              pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY]);
   2516       assert(!pipeline->gs ||
   2517              pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN]);
   2518 
   2519       if (cache_hit && cache != &pipeline->device->default_pipeline_cache)
   2520          pipeline_feedback.flags |=
   2521             VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
   2522 
   2523       goto success;
   2524    }
   2525 
   2526    if (pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)
   2527       return VK_PIPELINE_COMPILE_REQUIRED_EXT;
   2528 
   2529    /* Otherwise we try to get the NIR shaders (either from the original SPIR-V
   2530     * shader or the pipeline cache) and compile.
   2531     */
   2532    pipeline->shared_data =
   2533       v3dv_pipeline_shared_data_new_empty(pipeline_sha1, pipeline, true);
   2534 
   2535    pipeline->vs->feedback.flags |=
   2536       VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT;
   2537    if (pipeline->gs)
   2538       pipeline->gs->feedback.flags |=
   2539          VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT;
   2540    pipeline->fs->feedback.flags |=
   2541       VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT;
   2542 
   2543    if (!pipeline->vs->nir)
   2544       pipeline->vs->nir = pipeline_stage_get_nir(pipeline->vs, pipeline, cache);
   2545    if (pipeline->gs && !pipeline->gs->nir)
   2546       pipeline->gs->nir = pipeline_stage_get_nir(pipeline->gs, pipeline, cache);
   2547    if (!pipeline->fs->nir)
   2548       pipeline->fs->nir = pipeline_stage_get_nir(pipeline->fs, pipeline, cache);
   2549 
   2550    /* Linking + pipeline lowerings */
   2551    if (pipeline->gs) {
   2552       link_shaders(pipeline->gs->nir, pipeline->fs->nir);
   2553       link_shaders(pipeline->vs->nir, pipeline->gs->nir);
   2554    } else {
   2555       link_shaders(pipeline->vs->nir, pipeline->fs->nir);
   2556    }
   2557 
   2558    pipeline_lower_nir(pipeline, pipeline->fs, pipeline->layout);
   2559    lower_fs_io(pipeline->fs->nir);
   2560 
   2561    if (pipeline->gs) {
   2562       pipeline_lower_nir(pipeline, pipeline->gs, pipeline->layout);
   2563       lower_gs_io(pipeline->gs->nir);
   2564    }
   2565 
   2566    pipeline_lower_nir(pipeline, pipeline->vs, pipeline->layout);
   2567    lower_vs_io(pipeline->vs->nir);
   2568 
   2569    /* Compiling to vir */
   2570    VkResult vk_result;
   2571 
   2572    /* We should have got all the variants or no variants from the cache */
   2573    assert(!pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]);
   2574    vk_result = pipeline_compile_fragment_shader(pipeline, pAllocator, pCreateInfo);
   2575    if (vk_result != VK_SUCCESS)
   2576       return vk_result;
   2577 
   2578    assert(!pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY] &&
   2579           !pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN]);
   2580 
   2581    if (pipeline->gs) {
   2582       vk_result =
   2583          pipeline_compile_geometry_shader(pipeline, pAllocator, pCreateInfo);
   2584       if (vk_result != VK_SUCCESS)
   2585          return vk_result;
   2586    }
   2587 
   2588    assert(!pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX] &&
   2589           !pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]);
   2590 
   2591    vk_result = pipeline_compile_vertex_shader(pipeline, pAllocator, pCreateInfo);
   2592    if (vk_result != VK_SUCCESS)
   2593       return vk_result;
   2594 
   2595    if (!upload_assembly(pipeline))
   2596       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
   2597 
   2598    v3dv_pipeline_cache_upload_pipeline(pipeline, cache);
   2599 
   2600  success:
   2601 
   2602    pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
   2603    write_creation_feedback(pipeline,
   2604                            pCreateInfo->pNext,
   2605                            &pipeline_feedback,
   2606                            pCreateInfo->stageCount,
   2607                            pCreateInfo->pStages);
   2608 
   2609    /* Since we have the variants in the pipeline shared data we can now free
   2610     * the pipeline stages.
   2611     */
   2612    pipeline_free_stages(device, pipeline, pAllocator);
   2613 
   2614    pipeline_check_spill_size(pipeline);
   2615 
   2616    return compute_vpm_config(pipeline);
   2617 }
   2618 
   2619 static VkResult
   2620 compute_vpm_config(struct v3dv_pipeline *pipeline)
   2621 {
   2622    struct v3dv_shader_variant *vs_variant =
   2623       pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX];
   2624    struct v3dv_shader_variant *vs_bin_variant =
   2625       pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX];
   2626    struct v3d_vs_prog_data *vs = vs_variant->prog_data.vs;
   2627    struct v3d_vs_prog_data *vs_bin =vs_bin_variant->prog_data.vs;
   2628 
   2629    struct v3d_gs_prog_data *gs = NULL;
   2630    struct v3d_gs_prog_data *gs_bin = NULL;
   2631    if (pipeline->has_gs) {
   2632       struct v3dv_shader_variant *gs_variant =
   2633          pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY];
   2634       struct v3dv_shader_variant *gs_bin_variant =
   2635          pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN];
   2636       gs = gs_variant->prog_data.gs;
   2637       gs_bin = gs_bin_variant->prog_data.gs;
   2638    }
   2639 
   2640    if (!v3d_compute_vpm_config(&pipeline->device->devinfo,
   2641                                vs_bin, vs, gs_bin, gs,
   2642                                &pipeline->vpm_cfg_bin,
   2643                                &pipeline->vpm_cfg)) {
   2644       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
   2645    }
   2646 
   2647    return VK_SUCCESS;
   2648 }
   2649 
   2650 static unsigned
   2651 v3dv_dynamic_state_mask(VkDynamicState state)
   2652 {
   2653    switch(state) {
   2654    case VK_DYNAMIC_STATE_VIEWPORT:
   2655       return V3DV_DYNAMIC_VIEWPORT;
   2656    case VK_DYNAMIC_STATE_SCISSOR:
   2657       return V3DV_DYNAMIC_SCISSOR;
   2658    case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
   2659       return V3DV_DYNAMIC_STENCIL_COMPARE_MASK;
   2660    case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
   2661       return V3DV_DYNAMIC_STENCIL_WRITE_MASK;
   2662    case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
   2663       return V3DV_DYNAMIC_STENCIL_REFERENCE;
   2664    case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
   2665       return V3DV_DYNAMIC_BLEND_CONSTANTS;
   2666    case VK_DYNAMIC_STATE_DEPTH_BIAS:
   2667       return V3DV_DYNAMIC_DEPTH_BIAS;
   2668    case VK_DYNAMIC_STATE_LINE_WIDTH:
   2669       return V3DV_DYNAMIC_LINE_WIDTH;
   2670    case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
   2671       return V3DV_DYNAMIC_COLOR_WRITE_ENABLE;
   2672 
   2673    /* Depth bounds testing is not available in in V3D 4.2 so here we are just
   2674     * ignoring this dynamic state. We are already asserting at pipeline creation
   2675     * time that depth bounds testing is not enabled.
   2676     */
   2677    case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
   2678       return 0;
   2679 
   2680    default:
   2681       unreachable("Unhandled dynamic state");
   2682    }
   2683 }
   2684 
   2685 static void
   2686 pipeline_init_dynamic_state(
   2687    struct v3dv_pipeline *pipeline,
   2688    const VkPipelineDynamicStateCreateInfo *pDynamicState,
   2689    const VkPipelineViewportStateCreateInfo *pViewportState,
   2690    const VkPipelineDepthStencilStateCreateInfo *pDepthStencilState,
   2691    const VkPipelineColorBlendStateCreateInfo *pColorBlendState,
   2692    const VkPipelineRasterizationStateCreateInfo *pRasterizationState,
   2693    const VkPipelineColorWriteCreateInfoEXT *pColorWriteState)
   2694 {
   2695    pipeline->dynamic_state = default_dynamic_state;
   2696    struct v3dv_dynamic_state *dynamic = &pipeline->dynamic_state;
   2697 
   2698    /* Create a mask of enabled dynamic states */
   2699    uint32_t dynamic_states = 0;
   2700    if (pDynamicState) {
   2701       uint32_t count = pDynamicState->dynamicStateCount;
   2702       for (uint32_t s = 0; s < count; s++) {
   2703          dynamic_states |=
   2704             v3dv_dynamic_state_mask(pDynamicState->pDynamicStates[s]);
   2705       }
   2706    }
   2707 
   2708    /* For any pipeline states that are not dynamic, set the dynamic state
   2709     * from the static pipeline state.
   2710     */
   2711    if (pViewportState) {
   2712       if (!(dynamic_states & V3DV_DYNAMIC_VIEWPORT)) {
   2713          dynamic->viewport.count = pViewportState->viewportCount;
   2714          typed_memcpy(dynamic->viewport.viewports, pViewportState->pViewports,
   2715                       pViewportState->viewportCount);
   2716 
   2717          for (uint32_t i = 0; i < dynamic->viewport.count; i++) {
   2718             v3dv_viewport_compute_xform(&dynamic->viewport.viewports[i],
   2719                                         dynamic->viewport.scale[i],
   2720                                         dynamic->viewport.translate[i]);
   2721          }
   2722       }
   2723 
   2724       if (!(dynamic_states & V3DV_DYNAMIC_SCISSOR)) {
   2725          dynamic->scissor.count = pViewportState->scissorCount;
   2726          typed_memcpy(dynamic->scissor.scissors, pViewportState->pScissors,
   2727                       pViewportState->scissorCount);
   2728       }
   2729    }
   2730 
   2731    if (pDepthStencilState) {
   2732       if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_COMPARE_MASK)) {
   2733          dynamic->stencil_compare_mask.front =
   2734             pDepthStencilState->front.compareMask;
   2735          dynamic->stencil_compare_mask.back =
   2736             pDepthStencilState->back.compareMask;
   2737       }
   2738 
   2739       if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_WRITE_MASK)) {
   2740          dynamic->stencil_write_mask.front = pDepthStencilState->front.writeMask;
   2741          dynamic->stencil_write_mask.back = pDepthStencilState->back.writeMask;
   2742       }
   2743 
   2744       if (!(dynamic_states & V3DV_DYNAMIC_STENCIL_REFERENCE)) {
   2745          dynamic->stencil_reference.front = pDepthStencilState->front.reference;
   2746          dynamic->stencil_reference.back = pDepthStencilState->back.reference;
   2747       }
   2748    }
   2749 
   2750    if (pColorBlendState && !(dynamic_states & V3DV_DYNAMIC_BLEND_CONSTANTS)) {
   2751       memcpy(dynamic->blend_constants, pColorBlendState->blendConstants,
   2752              sizeof(dynamic->blend_constants));
   2753    }
   2754 
   2755    if (pRasterizationState) {
   2756       if (pRasterizationState->depthBiasEnable &&
   2757           !(dynamic_states & V3DV_DYNAMIC_DEPTH_BIAS)) {
   2758          dynamic->depth_bias.constant_factor =
   2759             pRasterizationState->depthBiasConstantFactor;
   2760          dynamic->depth_bias.depth_bias_clamp =
   2761             pRasterizationState->depthBiasClamp;
   2762          dynamic->depth_bias.slope_factor =
   2763             pRasterizationState->depthBiasSlopeFactor;
   2764       }
   2765       if (!(dynamic_states & V3DV_DYNAMIC_LINE_WIDTH))
   2766          dynamic->line_width = pRasterizationState->lineWidth;
   2767    }
   2768 
   2769    if (pColorWriteState && !(dynamic_states & V3DV_DYNAMIC_COLOR_WRITE_ENABLE)) {
   2770       dynamic->color_write_enable = 0;
   2771       for (uint32_t i = 0; i < pColorWriteState->attachmentCount; i++)
   2772          dynamic->color_write_enable |= pColorWriteState->pColorWriteEnables[i] ? (0xfu << (i * 4)) : 0;
   2773    }
   2774 
   2775    pipeline->dynamic_state.mask = dynamic_states;
   2776 }
   2777 
   2778 static bool
   2779 stencil_op_is_no_op(const VkStencilOpState *stencil)
   2780 {
   2781    return stencil->depthFailOp == VK_STENCIL_OP_KEEP &&
   2782           stencil->compareOp == VK_COMPARE_OP_ALWAYS;
   2783 }
   2784 
   2785 static void
   2786 enable_depth_bias(struct v3dv_pipeline *pipeline,
   2787                   const VkPipelineRasterizationStateCreateInfo *rs_info)
   2788 {
   2789    pipeline->depth_bias.enabled = false;
   2790    pipeline->depth_bias.is_z16 = false;
   2791 
   2792    if (!rs_info || !rs_info->depthBiasEnable)
   2793       return;
   2794 
   2795    /* Check the depth/stencil attachment description for the subpass used with
   2796     * this pipeline.
   2797     */
   2798    assert(pipeline->pass && pipeline->subpass);
   2799    struct v3dv_render_pass *pass = pipeline->pass;
   2800    struct v3dv_subpass *subpass = pipeline->subpass;
   2801 
   2802    if (subpass->ds_attachment.attachment == VK_ATTACHMENT_UNUSED)
   2803       return;
   2804 
   2805    assert(subpass->ds_attachment.attachment < pass->attachment_count);
   2806    struct v3dv_render_pass_attachment *att =
   2807       &pass->attachments[subpass->ds_attachment.attachment];
   2808 
   2809    if (att->desc.format == VK_FORMAT_D16_UNORM)
   2810       pipeline->depth_bias.is_z16 = true;
   2811 
   2812    pipeline->depth_bias.enabled = true;
   2813 }
   2814 
   2815 static void
   2816 pipeline_set_ez_state(struct v3dv_pipeline *pipeline,
   2817                       const VkPipelineDepthStencilStateCreateInfo *ds_info)
   2818 {
   2819    if (!ds_info || !ds_info->depthTestEnable) {
   2820       pipeline->ez_state = V3D_EZ_DISABLED;
   2821       return;
   2822    }
   2823 
   2824    switch (ds_info->depthCompareOp) {
   2825    case VK_COMPARE_OP_LESS:
   2826    case VK_COMPARE_OP_LESS_OR_EQUAL:
   2827       pipeline->ez_state = V3D_EZ_LT_LE;
   2828       break;
   2829    case VK_COMPARE_OP_GREATER:
   2830    case VK_COMPARE_OP_GREATER_OR_EQUAL:
   2831       pipeline->ez_state = V3D_EZ_GT_GE;
   2832       break;
   2833    case VK_COMPARE_OP_NEVER:
   2834    case VK_COMPARE_OP_EQUAL:
   2835       pipeline->ez_state = V3D_EZ_UNDECIDED;
   2836       break;
   2837    default:
   2838       pipeline->ez_state = V3D_EZ_DISABLED;
   2839       break;
   2840    }
   2841 
   2842    /* If stencil is enabled and is not a no-op, we need to disable EZ */
   2843    if (ds_info->stencilTestEnable &&
   2844        (!stencil_op_is_no_op(&ds_info->front) ||
   2845         !stencil_op_is_no_op(&ds_info->back))) {
   2846          pipeline->ez_state = V3D_EZ_DISABLED;
   2847    }
   2848 }
   2849 
   2850 static bool
   2851 pipeline_has_integer_vertex_attrib(struct v3dv_pipeline *pipeline)
   2852 {
   2853    for (uint8_t i = 0; i < pipeline->va_count; i++) {
   2854       if (vk_format_is_int(pipeline->va[i].vk_format))
   2855          return true;
   2856    }
   2857    return false;
   2858 }
   2859 
   2860 /* @pipeline can be NULL. We assume in that case that all the attributes have
   2861  * a float format (we only create an all-float BO once and we reuse it with
   2862  * all float pipelines), otherwise we look at the actual type of each
   2863  * attribute used with the specific pipeline passed in.
   2864  */
   2865 struct v3dv_bo *
   2866 v3dv_pipeline_create_default_attribute_values(struct v3dv_device *device,
   2867                                               struct v3dv_pipeline *pipeline)
   2868 {
   2869    uint32_t size = MAX_VERTEX_ATTRIBS * sizeof(float) * 4;
   2870    struct v3dv_bo *bo;
   2871 
   2872    bo = v3dv_bo_alloc(device, size, "default_vi_attributes", true);
   2873 
   2874    if (!bo) {
   2875       fprintf(stderr, "failed to allocate memory for the default "
   2876               "attribute values\n");
   2877       return NULL;
   2878    }
   2879 
   2880    bool ok = v3dv_bo_map(device, bo, size);
   2881    if (!ok) {
   2882       fprintf(stderr, "failed to map default attribute values buffer\n");
   2883       return false;
   2884    }
   2885 
   2886    uint32_t *attrs = bo->map;
   2887    uint8_t va_count = pipeline != NULL ? pipeline->va_count : 0;
   2888    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) {
   2889       attrs[i * 4 + 0] = 0;
   2890       attrs[i * 4 + 1] = 0;
   2891       attrs[i * 4 + 2] = 0;
   2892       VkFormat attr_format =
   2893          pipeline != NULL ? pipeline->va[i].vk_format : VK_FORMAT_UNDEFINED;
   2894       if (i < va_count && vk_format_is_int(attr_format)) {
   2895          attrs[i * 4 + 3] = 1;
   2896       } else {
   2897          attrs[i * 4 + 3] = fui(1.0);
   2898       }
   2899    }
   2900 
   2901    v3dv_bo_unmap(device, bo);
   2902 
   2903    return bo;
   2904 }
   2905 
   2906 static void
   2907 pipeline_set_sample_mask(struct v3dv_pipeline *pipeline,
   2908                          const VkPipelineMultisampleStateCreateInfo *ms_info)
   2909 {
   2910    pipeline->sample_mask = (1 << V3D_MAX_SAMPLES) - 1;
   2911 
   2912    /* Ignore pSampleMask if we are not enabling multisampling. The hardware
   2913     * requires this to be 0xf or 0x0 if using a single sample.
   2914     */
   2915    if (ms_info && ms_info->pSampleMask &&
   2916        ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT) {
   2917       pipeline->sample_mask &= ms_info->pSampleMask[0];
   2918    }
   2919 }
   2920 
   2921 static void
   2922 pipeline_set_sample_rate_shading(struct v3dv_pipeline *pipeline,
   2923                                  const VkPipelineMultisampleStateCreateInfo *ms_info)
   2924 {
   2925    pipeline->sample_rate_shading =
   2926       ms_info && ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT &&
   2927       ms_info->sampleShadingEnable;
   2928 }
   2929 
   2930 static VkResult
   2931 pipeline_init(struct v3dv_pipeline *pipeline,
   2932               struct v3dv_device *device,
   2933               struct v3dv_pipeline_cache *cache,
   2934               const VkGraphicsPipelineCreateInfo *pCreateInfo,
   2935               const VkAllocationCallbacks *pAllocator)
   2936 {
   2937    VkResult result = VK_SUCCESS;
   2938 
   2939    pipeline->device = device;
   2940 
   2941    V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, pCreateInfo->layout);
   2942    pipeline->layout = layout;
   2943 
   2944    V3DV_FROM_HANDLE(v3dv_render_pass, render_pass, pCreateInfo->renderPass);
   2945    assert(pCreateInfo->subpass < render_pass->subpass_count);
   2946    pipeline->pass = render_pass;
   2947    pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
   2948 
   2949    const VkPipelineInputAssemblyStateCreateInfo *ia_info =
   2950       pCreateInfo->pInputAssemblyState;
   2951    pipeline->topology = vk_to_pipe_prim_type[ia_info->topology];
   2952 
   2953    /* If rasterization is not enabled, various CreateInfo structs must be
   2954     * ignored.
   2955     */
   2956    const bool raster_enabled =
   2957       !pCreateInfo->pRasterizationState->rasterizerDiscardEnable;
   2958 
   2959    const VkPipelineViewportStateCreateInfo *vp_info =
   2960       raster_enabled ? pCreateInfo->pViewportState : NULL;
   2961 
   2962    const VkPipelineDepthStencilStateCreateInfo *ds_info =
   2963       raster_enabled ? pCreateInfo->pDepthStencilState : NULL;
   2964 
   2965    const VkPipelineRasterizationStateCreateInfo *rs_info =
   2966       raster_enabled ? pCreateInfo->pRasterizationState : NULL;
   2967 
   2968    const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info =
   2969       rs_info ? vk_find_struct_const(
   2970          rs_info->pNext,
   2971          PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT) :
   2972             NULL;
   2973 
   2974    const VkPipelineColorBlendStateCreateInfo *cb_info =
   2975       raster_enabled ? pCreateInfo->pColorBlendState : NULL;
   2976 
   2977    const VkPipelineMultisampleStateCreateInfo *ms_info =
   2978       raster_enabled ? pCreateInfo->pMultisampleState : NULL;
   2979 
   2980    const VkPipelineColorWriteCreateInfoEXT *cw_info =
   2981       cb_info ? vk_find_struct_const(cb_info->pNext,
   2982                                      PIPELINE_COLOR_WRITE_CREATE_INFO_EXT) :
   2983                 NULL;
   2984 
   2985    pipeline_init_dynamic_state(pipeline,
   2986                                pCreateInfo->pDynamicState,
   2987                                vp_info, ds_info, cb_info, rs_info, cw_info);
   2988 
   2989    /* V3D 4.2 doesn't support depth bounds testing so we don't advertise that
   2990     * feature and it shouldn't be used by any pipeline.
   2991     */
   2992    assert(!ds_info || !ds_info->depthBoundsTestEnable);
   2993 
   2994    v3dv_X(device, pipeline_pack_state)(pipeline, cb_info, ds_info,
   2995                                        rs_info, pv_info, ms_info);
   2996 
   2997    pipeline_set_ez_state(pipeline, ds_info);
   2998    enable_depth_bias(pipeline, rs_info);
   2999    pipeline_set_sample_mask(pipeline, ms_info);
   3000    pipeline_set_sample_rate_shading(pipeline, ms_info);
   3001 
   3002    pipeline->primitive_restart =
   3003       pCreateInfo->pInputAssemblyState->primitiveRestartEnable;
   3004 
   3005    result = pipeline_compile_graphics(pipeline, cache, pCreateInfo, pAllocator);
   3006 
   3007    if (result != VK_SUCCESS) {
   3008       /* Caller would already destroy the pipeline, and we didn't allocate any
   3009        * extra info. We don't need to do anything else.
   3010        */
   3011       return result;
   3012    }
   3013 
   3014    const VkPipelineVertexInputStateCreateInfo *vi_info =
   3015       pCreateInfo->pVertexInputState;
   3016 
   3017    const VkPipelineVertexInputDivisorStateCreateInfoEXT *vd_info =
   3018       vk_find_struct_const(vi_info->pNext,
   3019                            PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
   3020 
   3021    v3dv_X(device, pipeline_pack_compile_state)(pipeline, vi_info, vd_info);
   3022 
   3023    if (pipeline_has_integer_vertex_attrib(pipeline)) {
   3024       pipeline->default_attribute_values =
   3025          v3dv_pipeline_create_default_attribute_values(pipeline->device, pipeline);
   3026       if (!pipeline->default_attribute_values)
   3027          return VK_ERROR_OUT_OF_DEVICE_MEMORY;
   3028    } else {
   3029       pipeline->default_attribute_values = NULL;
   3030    }
   3031 
   3032    return result;
   3033 }
   3034 
   3035 static VkResult
   3036 graphics_pipeline_create(VkDevice _device,
   3037                          VkPipelineCache _cache,
   3038                          const VkGraphicsPipelineCreateInfo *pCreateInfo,
   3039                          const VkAllocationCallbacks *pAllocator,
   3040                          VkPipeline *pPipeline)
   3041 {
   3042    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   3043    V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache);
   3044 
   3045    struct v3dv_pipeline *pipeline;
   3046    VkResult result;
   3047 
   3048    /* Use the default pipeline cache if none is specified */
   3049    if (cache == NULL && device->instance->default_pipeline_cache_enabled)
   3050       cache = &device->default_pipeline_cache;
   3051 
   3052    pipeline = vk_object_zalloc(&device->vk, pAllocator, sizeof(*pipeline),
   3053                                VK_OBJECT_TYPE_PIPELINE);
   3054 
   3055    if (pipeline == NULL)
   3056       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
   3057 
   3058    result = pipeline_init(pipeline, device, cache,
   3059                           pCreateInfo,
   3060                           pAllocator);
   3061 
   3062    if (result != VK_SUCCESS) {
   3063       v3dv_destroy_pipeline(pipeline, device, pAllocator);
   3064       if (result == VK_PIPELINE_COMPILE_REQUIRED_EXT)
   3065          *pPipeline = VK_NULL_HANDLE;
   3066       return result;
   3067    }
   3068 
   3069    *pPipeline = v3dv_pipeline_to_handle(pipeline);
   3070 
   3071    return VK_SUCCESS;
   3072 }
   3073 
   3074 VKAPI_ATTR VkResult VKAPI_CALL
   3075 v3dv_CreateGraphicsPipelines(VkDevice _device,
   3076                              VkPipelineCache pipelineCache,
   3077                              uint32_t count,
   3078                              const VkGraphicsPipelineCreateInfo *pCreateInfos,
   3079                              const VkAllocationCallbacks *pAllocator,
   3080                              VkPipeline *pPipelines)
   3081 {
   3082    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   3083    VkResult result = VK_SUCCESS;
   3084 
   3085    if (unlikely(V3D_DEBUG & V3D_DEBUG_SHADERS))
   3086       mtx_lock(&device->pdevice->mutex);
   3087 
   3088    uint32_t i = 0;
   3089    for (; i < count; i++) {
   3090       VkResult local_result;
   3091 
   3092       local_result = graphics_pipeline_create(_device,
   3093                                               pipelineCache,
   3094                                               &pCreateInfos[i],
   3095                                               pAllocator,
   3096                                               &pPipelines[i]);
   3097 
   3098       if (local_result != VK_SUCCESS) {
   3099          result = local_result;
   3100          pPipelines[i] = VK_NULL_HANDLE;
   3101 
   3102          if (pCreateInfos[i].flags &
   3103              VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT)
   3104             break;
   3105       }
   3106    }
   3107 
   3108    for (; i < count; i++)
   3109       pPipelines[i] = VK_NULL_HANDLE;
   3110 
   3111    if (unlikely(V3D_DEBUG & V3D_DEBUG_SHADERS))
   3112       mtx_unlock(&device->pdevice->mutex);
   3113 
   3114    return result;
   3115 }
   3116 
   3117 static void
   3118 shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
   3119 {
   3120    assert(glsl_type_is_vector_or_scalar(type));
   3121 
   3122    uint32_t comp_size = glsl_type_is_boolean(type)
   3123       ? 4 : glsl_get_bit_size(type) / 8;
   3124    unsigned length = glsl_get_vector_elements(type);
   3125    *size = comp_size * length,
   3126    *align = comp_size * (length == 3 ? 4 : length);
   3127 }
   3128 
   3129 static void
   3130 lower_cs_shared(struct nir_shader *nir)
   3131 {
   3132    NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
   3133               nir_var_mem_shared, shared_type_info);
   3134    NIR_PASS_V(nir, nir_lower_explicit_io,
   3135               nir_var_mem_shared, nir_address_format_32bit_offset);
   3136 }
   3137 
   3138 static VkResult
   3139 pipeline_compile_compute(struct v3dv_pipeline *pipeline,
   3140                          struct v3dv_pipeline_cache *cache,
   3141                          const VkComputePipelineCreateInfo *info,
   3142                          const VkAllocationCallbacks *alloc)
   3143 {
   3144    VkPipelineCreationFeedbackEXT pipeline_feedback = {
   3145       .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT,
   3146    };
   3147    int64_t pipeline_start = os_time_get_nano();
   3148 
   3149    struct v3dv_device *device = pipeline->device;
   3150    struct v3dv_physical_device *physical_device =
   3151       &device->instance->physicalDevice;
   3152 
   3153    const VkPipelineShaderStageCreateInfo *sinfo = &info->stage;
   3154    gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
   3155 
   3156    struct v3dv_pipeline_stage *p_stage =
   3157       vk_zalloc2(&device->vk.alloc, alloc, sizeof(*p_stage), 8,
   3158                  VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
   3159    if (!p_stage)
   3160       return VK_ERROR_OUT_OF_HOST_MEMORY;
   3161 
   3162    p_stage->program_id = p_atomic_inc_return(&physical_device->next_program_id);
   3163    p_stage->pipeline = pipeline;
   3164    p_stage->stage = gl_shader_stage_to_broadcom(stage);
   3165    p_stage->entrypoint = sinfo->pName;
   3166    p_stage->module = vk_shader_module_from_handle(sinfo->module);
   3167    p_stage->spec_info = sinfo->pSpecializationInfo;
   3168    p_stage->feedback = (VkPipelineCreationFeedbackEXT) { 0 };
   3169 
   3170    pipeline_hash_shader(p_stage->module,
   3171                         p_stage->entrypoint,
   3172                         stage,
   3173                         p_stage->spec_info,
   3174                         p_stage->shader_sha1);
   3175 
   3176    /* We try to get directly the variant first from the cache */
   3177    p_stage->nir = NULL;
   3178 
   3179    pipeline->cs = p_stage;
   3180    pipeline->active_stages |= sinfo->stage;
   3181 
   3182    struct v3dv_pipeline_key pipeline_key;
   3183    pipeline_populate_compute_key(pipeline, &pipeline_key, info);
   3184    unsigned char pipeline_sha1[20];
   3185    pipeline_hash_compute(pipeline, &pipeline_key, pipeline_sha1);
   3186 
   3187    bool cache_hit = false;
   3188    pipeline->shared_data =
   3189       v3dv_pipeline_cache_search_for_pipeline(cache, pipeline_sha1, &cache_hit);
   3190 
   3191    if (pipeline->shared_data != NULL) {
   3192       assert(pipeline->shared_data->variants[BROADCOM_SHADER_COMPUTE]);
   3193       if (cache_hit && cache != &pipeline->device->default_pipeline_cache)
   3194          pipeline_feedback.flags |=
   3195             VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
   3196 
   3197       goto success;
   3198    }
   3199 
   3200    if (info->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)
   3201       return VK_PIPELINE_COMPILE_REQUIRED_EXT;
   3202 
   3203    pipeline->shared_data = v3dv_pipeline_shared_data_new_empty(pipeline_sha1,
   3204                                                                pipeline,
   3205                                                                false);
   3206 
   3207    p_stage->feedback.flags |= VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT;
   3208 
   3209    /* If not found on cache, compile it */
   3210    p_stage->nir = pipeline_stage_get_nir(p_stage, pipeline, cache);
   3211    assert(p_stage->nir);
   3212 
   3213    st_nir_opts(p_stage->nir);
   3214    pipeline_lower_nir(pipeline, p_stage, pipeline->layout);
   3215    lower_cs_shared(p_stage->nir);
   3216 
   3217    VkResult result = VK_SUCCESS;
   3218 
   3219    struct v3d_key key;
   3220    memset(&key, 0, sizeof(key));
   3221    pipeline_populate_v3d_key(&key, p_stage, 0,
   3222                              pipeline->device->features.robustBufferAccess);
   3223    pipeline->shared_data->variants[BROADCOM_SHADER_COMPUTE] =
   3224       pipeline_compile_shader_variant(p_stage, &key, sizeof(key),
   3225                                       alloc, &result);
   3226 
   3227    if (result != VK_SUCCESS)
   3228       return result;
   3229 
   3230    if (!upload_assembly(pipeline))
   3231       return VK_ERROR_OUT_OF_DEVICE_MEMORY;
   3232 
   3233    v3dv_pipeline_cache_upload_pipeline(pipeline, cache);
   3234 
   3235 success:
   3236 
   3237    pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
   3238    write_creation_feedback(pipeline,
   3239                            info->pNext,
   3240                            &pipeline_feedback,
   3241                            1,
   3242                            &info->stage);
   3243 
   3244    /* As we got the variants in pipeline->shared_data, after compiling we
   3245     * don't need the pipeline_stages
   3246     */
   3247    pipeline_free_stages(device, pipeline, alloc);
   3248 
   3249    pipeline_check_spill_size(pipeline);
   3250 
   3251    return VK_SUCCESS;
   3252 }
   3253 
   3254 static VkResult
   3255 compute_pipeline_init(struct v3dv_pipeline *pipeline,
   3256                       struct v3dv_device *device,
   3257                       struct v3dv_pipeline_cache *cache,
   3258                       const VkComputePipelineCreateInfo *info,
   3259                       const VkAllocationCallbacks *alloc)
   3260 {
   3261    V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, info->layout);
   3262 
   3263    pipeline->device = device;
   3264    pipeline->layout = layout;
   3265 
   3266    VkResult result = pipeline_compile_compute(pipeline, cache, info, alloc);
   3267 
   3268    return result;
   3269 }
   3270 
   3271 static VkResult
   3272 compute_pipeline_create(VkDevice _device,
   3273                          VkPipelineCache _cache,
   3274                          const VkComputePipelineCreateInfo *pCreateInfo,
   3275                          const VkAllocationCallbacks *pAllocator,
   3276                          VkPipeline *pPipeline)
   3277 {
   3278    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   3279    V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache);
   3280 
   3281    struct v3dv_pipeline *pipeline;
   3282    VkResult result;
   3283 
   3284    /* Use the default pipeline cache if none is specified */
   3285    if (cache == NULL && device->instance->default_pipeline_cache_enabled)
   3286       cache = &device->default_pipeline_cache;
   3287 
   3288    pipeline = vk_object_zalloc(&device->vk, pAllocator, sizeof(*pipeline),
   3289                                VK_OBJECT_TYPE_PIPELINE);
   3290    if (pipeline == NULL)
   3291       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
   3292 
   3293    result = compute_pipeline_init(pipeline, device, cache,
   3294                                   pCreateInfo, pAllocator);
   3295    if (result != VK_SUCCESS) {
   3296       v3dv_destroy_pipeline(pipeline, device, pAllocator);
   3297       if (result == VK_PIPELINE_COMPILE_REQUIRED_EXT)
   3298          *pPipeline = VK_NULL_HANDLE;
   3299       return result;
   3300    }
   3301 
   3302    *pPipeline = v3dv_pipeline_to_handle(pipeline);
   3303 
   3304    return VK_SUCCESS;
   3305 }
   3306 
   3307 VKAPI_ATTR VkResult VKAPI_CALL
   3308 v3dv_CreateComputePipelines(VkDevice _device,
   3309                             VkPipelineCache pipelineCache,
   3310                             uint32_t createInfoCount,
   3311                             const VkComputePipelineCreateInfo *pCreateInfos,
   3312                             const VkAllocationCallbacks *pAllocator,
   3313                             VkPipeline *pPipelines)
   3314 {
   3315    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   3316    VkResult result = VK_SUCCESS;
   3317 
   3318    if (unlikely(V3D_DEBUG & V3D_DEBUG_SHADERS))
   3319       mtx_lock(&device->pdevice->mutex);
   3320 
   3321    uint32_t i = 0;
   3322    for (; i < createInfoCount; i++) {
   3323       VkResult local_result;
   3324       local_result = compute_pipeline_create(_device,
   3325                                               pipelineCache,
   3326                                               &pCreateInfos[i],
   3327                                               pAllocator,
   3328                                               &pPipelines[i]);
   3329 
   3330       if (local_result != VK_SUCCESS) {
   3331          result = local_result;
   3332          pPipelines[i] = VK_NULL_HANDLE;
   3333 
   3334          if (pCreateInfos[i].flags &
   3335              VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT)
   3336             break;
   3337       }
   3338    }
   3339 
   3340    for (; i < createInfoCount; i++)
   3341       pPipelines[i] = VK_NULL_HANDLE;
   3342 
   3343    if (unlikely(V3D_DEBUG & V3D_DEBUG_SHADERS))
   3344       mtx_unlock(&device->pdevice->mutex);
   3345 
   3346    return result;
   3347 }
   3348