1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Intel Corporation 3bf215546Sopenharmony_ci * Copyright © 2020 Valve Corporation 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "nir_control_flow.h" 26bf215546Sopenharmony_ci#include "nir_builder.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/** 29bf215546Sopenharmony_ci * This file implements an optimization for multiview. Some GPU's have a 30bf215546Sopenharmony_ci * special mode which allows the vertex shader (or last stage in the geometry 31bf215546Sopenharmony_ci * pipeline) to create multiple primitives in different layers of the 32bf215546Sopenharmony_ci * framebuffer at once by writing multiple copies of gl_Position. The 33bf215546Sopenharmony_ci * assumption is that in most uses of multiview, the only use of gl_ViewIndex 34bf215546Sopenharmony_ci * is to change the position to implement the parallax effect, and other 35bf215546Sopenharmony_ci * varyings will be the same between the different views. We put the body of 36bf215546Sopenharmony_ci * the original vertex shader in a loop, writing to a different copy of 37bf215546Sopenharmony_ci * gl_Position each loop iteration, and then let other optimizations clean up 38bf215546Sopenharmony_ci * the mess. 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_cistatic bool 42bf215546Sopenharmony_cishader_writes_to_memory(nir_shader *shader) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci /* With multiview, we would need to ensure that memory writes happen either 45bf215546Sopenharmony_ci * once or once per view. Since combination of multiview and memory writes 46bf215546Sopenharmony_ci * is not expected, we'll just skip this optimization in this case. 47bf215546Sopenharmony_ci */ 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci nir_function_impl *entrypoint = nir_shader_get_entrypoint(shader); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci nir_foreach_block(block, entrypoint) { 52bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 53bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 54bf215546Sopenharmony_ci continue; 55bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci switch (intrin->intrinsic) { 58bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_add: 59bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_imin: 60bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_umin: 61bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_imax: 62bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_umax: 63bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_and: 64bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_or: 65bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_xor: 66bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_exchange: 67bf215546Sopenharmony_ci case nir_intrinsic_deref_atomic_comp_swap: 68bf215546Sopenharmony_ci case nir_intrinsic_store_ssbo: 69bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_add: 70bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imin: 71bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umin: 72bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imax: 73bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umax: 74bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_and: 75bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_or: 76bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_xor: 77bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_exchange: 78bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_comp_swap: 79bf215546Sopenharmony_ci case nir_intrinsic_store_shared: 80bf215546Sopenharmony_ci case nir_intrinsic_store_shared2_amd: 81bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_add: 82bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_imin: 83bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_umin: 84bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_imax: 85bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_umax: 86bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_and: 87bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_or: 88bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_xor: 89bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_exchange: 90bf215546Sopenharmony_ci case nir_intrinsic_shared_atomic_comp_swap: 91bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_add: 92bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_imin: 93bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_umin: 94bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_imax: 95bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_umax: 96bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_and: 97bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_or: 98bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_xor: 99bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_exchange: 100bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_comp_swap: 101bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_fadd: 102bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_fmin: 103bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_fmax: 104bf215546Sopenharmony_ci case nir_intrinsic_task_payload_atomic_fcomp_swap: 105bf215546Sopenharmony_ci case nir_intrinsic_image_deref_store: 106bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_add: 107bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_fadd: 108bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umin: 109bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umax: 110bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imin: 111bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imax: 112bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_fmin: 113bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_fmax: 114bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_and: 115bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_or: 116bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_xor: 117bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_exchange: 118bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_comp_swap: 119bf215546Sopenharmony_ci return true; 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci default: 122bf215546Sopenharmony_ci /* Keep walking. */ 123bf215546Sopenharmony_ci break; 124bf215546Sopenharmony_ci } 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci return false; 129bf215546Sopenharmony_ci} 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cibool 132bf215546Sopenharmony_cinir_shader_uses_view_index(nir_shader *shader) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci nir_function_impl *entrypoint = nir_shader_get_entrypoint(shader); 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci nir_foreach_block(block, entrypoint) { 137bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 138bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 139bf215546Sopenharmony_ci continue; 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 142bf215546Sopenharmony_ci if (intrin->intrinsic == nir_intrinsic_load_view_index) 143bf215546Sopenharmony_ci return true; 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci } 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci return false; 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_cistatic bool 151bf215546Sopenharmony_cishader_only_position_uses_view_index(nir_shader *shader) 152bf215546Sopenharmony_ci{ 153bf215546Sopenharmony_ci nir_shader *shader_no_position = nir_shader_clone(NULL, shader); 154bf215546Sopenharmony_ci nir_function_impl *entrypoint = nir_shader_get_entrypoint(shader_no_position); 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci /* Remove the store position from a cloned shader. */ 157bf215546Sopenharmony_ci nir_foreach_block(block, entrypoint) { 158bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 159bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 160bf215546Sopenharmony_ci continue; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci nir_intrinsic_instr *store = nir_instr_as_intrinsic(instr); 163bf215546Sopenharmony_ci if (store->intrinsic != nir_intrinsic_store_deref) 164bf215546Sopenharmony_ci continue; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci nir_variable *var = nir_intrinsic_get_var(store, 0); 167bf215546Sopenharmony_ci if (var->data.location != VARYING_SLOT_POS) 168bf215546Sopenharmony_ci continue; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci nir_instr_remove(&store->instr); 171bf215546Sopenharmony_ci } 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci /* Clean up shader so unused load_view_index intrinsics are removed. */ 175bf215546Sopenharmony_ci bool progress; 176bf215546Sopenharmony_ci do { 177bf215546Sopenharmony_ci progress = false; 178bf215546Sopenharmony_ci progress |= nir_opt_dead_cf(shader_no_position); 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci /* Peephole select will drop if-blocks that have then and else empty, 181bf215546Sopenharmony_ci * which will remove the usage of an SSA in the condition. 182bf215546Sopenharmony_ci */ 183bf215546Sopenharmony_ci progress |= nir_opt_peephole_select(shader_no_position, 0, false, false); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci progress |= nir_opt_dce(shader_no_position); 186bf215546Sopenharmony_ci } while (progress); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci bool uses_view_index = nir_shader_uses_view_index(shader_no_position); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci ralloc_free(shader_no_position); 191bf215546Sopenharmony_ci return !uses_view_index; 192bf215546Sopenharmony_ci} 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci/* Return true if it's safe to call nir_lower_multiview() on this vertex 195bf215546Sopenharmony_ci * shader. Note that this only handles driver-agnostic checks, i.e. things 196bf215546Sopenharmony_ci * which would make nir_lower_multiview() incorrect. Any driver-specific 197bf215546Sopenharmony_ci * checks, e.g. for sufficient varying space or performance considerations, 198bf215546Sopenharmony_ci * should be handled in the driver. 199bf215546Sopenharmony_ci * 200bf215546Sopenharmony_ci * Note that we don't handle the more complex checks needed for lowering 201bf215546Sopenharmony_ci * pipelines with geometry or tessellation shaders. 202bf215546Sopenharmony_ci */ 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_cibool 205bf215546Sopenharmony_cinir_can_lower_multiview(nir_shader *shader) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci bool writes_position = false; 208bf215546Sopenharmony_ci nir_foreach_shader_out_variable(var, shader) { 209bf215546Sopenharmony_ci if (var->data.location == VARYING_SLOT_POS) { 210bf215546Sopenharmony_ci writes_position = true; 211bf215546Sopenharmony_ci break; 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci /* Don't bother handling this edge case. */ 216bf215546Sopenharmony_ci if (!writes_position) 217bf215546Sopenharmony_ci return false; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci return !shader_writes_to_memory(shader) && 220bf215546Sopenharmony_ci shader_only_position_uses_view_index(shader); 221bf215546Sopenharmony_ci} 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci/** 224bf215546Sopenharmony_ci * The lowering. Call with the last active geometry stage. 225bf215546Sopenharmony_ci */ 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_cibool 228bf215546Sopenharmony_cinir_lower_multiview(nir_shader *shader, uint32_t view_mask) 229bf215546Sopenharmony_ci{ 230bf215546Sopenharmony_ci assert(shader->info.stage != MESA_SHADER_FRAGMENT); 231bf215546Sopenharmony_ci int view_count = util_bitcount(view_mask); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci nir_function_impl *entrypoint = nir_shader_get_entrypoint(shader); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci /* Update position to refer to an array. */ 236bf215546Sopenharmony_ci nir_variable *pos_var = NULL; 237bf215546Sopenharmony_ci nir_foreach_shader_out_variable(var, shader) { 238bf215546Sopenharmony_ci if (var->data.location == VARYING_SLOT_POS) { 239bf215546Sopenharmony_ci assert(var->type == glsl_vec4_type()); 240bf215546Sopenharmony_ci var->type = glsl_array_type(glsl_vec4_type(), view_count, 0); 241bf215546Sopenharmony_ci var->data.per_view = true; 242bf215546Sopenharmony_ci pos_var = var; 243bf215546Sopenharmony_ci break; 244bf215546Sopenharmony_ci } 245bf215546Sopenharmony_ci } 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci assert(pos_var); 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci nir_cf_list body; 250bf215546Sopenharmony_ci nir_cf_list_extract(&body, &entrypoint->body); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci nir_builder b; 253bf215546Sopenharmony_ci nir_builder_init(&b, entrypoint); 254bf215546Sopenharmony_ci b.cursor = nir_after_cf_list(&entrypoint->body); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci /* Loop Index will go from 0 to view_count. */ 257bf215546Sopenharmony_ci nir_variable *loop_index_var = 258bf215546Sopenharmony_ci nir_local_variable_create(entrypoint, glsl_uint_type(), "loop_index"); 259bf215546Sopenharmony_ci nir_deref_instr *loop_index_deref = nir_build_deref_var(&b, loop_index_var); 260bf215546Sopenharmony_ci nir_store_deref(&b, loop_index_deref, nir_imm_int(&b, 0), 1); 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci /* Array of view index values that are active in the loop. Note that the 263bf215546Sopenharmony_ci * loop index only matches the view index if there are no gaps in the 264bf215546Sopenharmony_ci * view_mask. 265bf215546Sopenharmony_ci */ 266bf215546Sopenharmony_ci nir_variable *view_index_var = nir_local_variable_create( 267bf215546Sopenharmony_ci entrypoint, glsl_array_type(glsl_uint_type(), view_count, 0), "view_index"); 268bf215546Sopenharmony_ci nir_deref_instr *view_index_deref = nir_build_deref_var(&b, view_index_var); 269bf215546Sopenharmony_ci { 270bf215546Sopenharmony_ci int array_position = 0; 271bf215546Sopenharmony_ci uint32_t view_mask_temp = view_mask; 272bf215546Sopenharmony_ci while (view_mask_temp) { 273bf215546Sopenharmony_ci uint32_t view_index = u_bit_scan(&view_mask_temp); 274bf215546Sopenharmony_ci nir_store_deref(&b, nir_build_deref_array_imm(&b, view_index_deref, array_position), 275bf215546Sopenharmony_ci nir_imm_int(&b, view_index), 1); 276bf215546Sopenharmony_ci array_position++; 277bf215546Sopenharmony_ci } 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci /* Create the equivalent of 281bf215546Sopenharmony_ci * 282bf215546Sopenharmony_ci * while (true): 283bf215546Sopenharmony_ci * if (loop_index >= view_count): 284bf215546Sopenharmony_ci * break 285bf215546Sopenharmony_ci * 286bf215546Sopenharmony_ci * view_index = active_indices[loop_index] 287bf215546Sopenharmony_ci * pos_deref = &pos[loop_index] 288bf215546Sopenharmony_ci * 289bf215546Sopenharmony_ci * # Placeholder for the body to be reinserted. 290bf215546Sopenharmony_ci * 291bf215546Sopenharmony_ci * loop_index += 1 292bf215546Sopenharmony_ci * 293bf215546Sopenharmony_ci * Later both `view_index` and `pos_deref` will be used to rewrite the 294bf215546Sopenharmony_ci * original shader body. 295bf215546Sopenharmony_ci */ 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci nir_loop* loop = nir_push_loop(&b); 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci nir_ssa_def *loop_index = nir_load_deref(&b, loop_index_deref); 300bf215546Sopenharmony_ci nir_ssa_def *cmp = nir_ige(&b, loop_index, nir_imm_int(&b, view_count)); 301bf215546Sopenharmony_ci nir_if *loop_check = nir_push_if(&b, cmp); 302bf215546Sopenharmony_ci nir_jump(&b, nir_jump_break); 303bf215546Sopenharmony_ci nir_pop_if(&b, loop_check); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci nir_ssa_def *view_index = 306bf215546Sopenharmony_ci nir_load_deref(&b, nir_build_deref_array(&b, view_index_deref, loop_index)); 307bf215546Sopenharmony_ci nir_deref_instr *pos_deref = 308bf215546Sopenharmony_ci nir_build_deref_array(&b, nir_build_deref_var(&b, pos_var), loop_index); 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci nir_store_deref(&b, loop_index_deref, nir_iadd_imm(&b, loop_index, 1), 1); 311bf215546Sopenharmony_ci nir_pop_loop(&b, loop); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci /* Reinsert the body. */ 314bf215546Sopenharmony_ci b.cursor = nir_after_instr(&pos_deref->instr); 315bf215546Sopenharmony_ci nir_cf_reinsert(&body, b.cursor); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci nir_foreach_block(block, entrypoint) { 318bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 319bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 320bf215546Sopenharmony_ci continue; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci switch (intrin->intrinsic) { 325bf215546Sopenharmony_ci case nir_intrinsic_load_view_index: { 326bf215546Sopenharmony_ci assert(intrin->dest.is_ssa); 327bf215546Sopenharmony_ci nir_ssa_def_rewrite_uses(&intrin->dest.ssa, view_index); 328bf215546Sopenharmony_ci break; 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci case nir_intrinsic_store_deref: { 332bf215546Sopenharmony_ci nir_variable *var = nir_intrinsic_get_var(intrin, 0); 333bf215546Sopenharmony_ci if (var == pos_var) { 334bf215546Sopenharmony_ci nir_deref_instr *old_deref = nir_src_as_deref(intrin->src[0]); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci nir_instr_rewrite_src(instr, &intrin->src[0], 337bf215546Sopenharmony_ci nir_src_for_ssa(&pos_deref->dest.ssa)); 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci /* Remove old deref since it has the wrong type. */ 340bf215546Sopenharmony_ci nir_deref_instr_remove_if_unused(old_deref); 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci break; 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci case nir_intrinsic_load_deref: 346bf215546Sopenharmony_ci if (nir_intrinsic_get_var(intrin, 0) == pos_var) { 347bf215546Sopenharmony_ci unreachable("Should have lowered I/O to temporaries " 348bf215546Sopenharmony_ci "so no load_deref on position output is expected."); 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci break; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci case nir_intrinsic_copy_deref: 353bf215546Sopenharmony_ci unreachable("Should have lowered copy_derefs at this point"); 354bf215546Sopenharmony_ci break; 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci default: 357bf215546Sopenharmony_ci /* Do nothing. */ 358bf215546Sopenharmony_ci break; 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci nir_metadata_preserve(entrypoint, nir_metadata_none); 364bf215546Sopenharmony_ci return true; 365bf215546Sopenharmony_ci} 366bf215546Sopenharmony_ci 367