1/* 2 * Copyright (C) 2020-2021 Collabora, Ltd. 3 * Copyright © 2020 Valve Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25#include "compiler/nir/nir.h" 26#include "compiler/nir/nir_builder.h" 27#include "midgard_nir.h" 28 29static bool 30nir_lower_helper_writes(nir_builder *b, nir_instr *instr, UNUSED void *data) 31{ 32 if (instr->type != nir_instr_type_intrinsic) 33 return false; 34 35 nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); 36 37 switch (intr->intrinsic) { 38 case nir_intrinsic_global_atomic_add: 39 case nir_intrinsic_global_atomic_and: 40 case nir_intrinsic_global_atomic_comp_swap: 41 case nir_intrinsic_global_atomic_exchange: 42 case nir_intrinsic_global_atomic_fadd: 43 case nir_intrinsic_global_atomic_fcomp_swap: 44 case nir_intrinsic_global_atomic_fmax: 45 case nir_intrinsic_global_atomic_fmin: 46 case nir_intrinsic_global_atomic_imax: 47 case nir_intrinsic_global_atomic_imin: 48 case nir_intrinsic_global_atomic_or: 49 case nir_intrinsic_global_atomic_umax: 50 case nir_intrinsic_global_atomic_umin: 51 case nir_intrinsic_global_atomic_xor: 52 case nir_intrinsic_image_atomic_add: 53 case nir_intrinsic_image_atomic_and: 54 case nir_intrinsic_image_atomic_comp_swap: 55 case nir_intrinsic_image_atomic_dec_wrap: 56 case nir_intrinsic_image_atomic_exchange: 57 case nir_intrinsic_image_atomic_fadd: 58 case nir_intrinsic_image_atomic_imax: 59 case nir_intrinsic_image_atomic_imin: 60 case nir_intrinsic_image_atomic_inc_wrap: 61 case nir_intrinsic_image_atomic_or: 62 case nir_intrinsic_image_atomic_umax: 63 case nir_intrinsic_image_atomic_umin: 64 case nir_intrinsic_image_atomic_xor: 65 case nir_intrinsic_image_store: 66 case nir_intrinsic_store_global: 67 break; 68 default: 69 return false; 70 } 71 72 b->cursor = nir_before_instr(instr); 73 74 nir_ssa_def *helper = nir_load_helper_invocation(b, 1); 75 nir_push_if(b, nir_inot(b, helper)); 76 nir_instr_remove(instr); 77 nir_builder_instr_insert(b, instr); 78 nir_pop_if(b, NULL); 79 80 return true; 81} 82 83bool 84midgard_nir_lower_helper_writes(nir_shader *shader) 85{ 86 if (shader->info.stage != MESA_SHADER_FRAGMENT) 87 return false; 88 89 return nir_shader_instructions_pass(shader, 90 nir_lower_helper_writes, 91 nir_metadata_none, 92 NULL); 93} 94