| /************************************************************************** |
| * |
| * Copyright 2019 Red Hat. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| **************************************************************************/ |
| |
| #ifndef LP_BLD_NIR_H |
| #define LP_BLD_NIR_H |
| |
| #include "gallivm/lp_bld.h" |
| #include "gallivm/lp_bld_limits.h" |
| #include "lp_bld_type.h" |
| |
| #include "gallivm/lp_bld_tgsi.h" |
| #include "nir.h" |
| |
| struct nir_shader; |
| |
| void lp_build_nir_soa(struct gallivm_state *gallivm, |
| struct nir_shader *shader, |
| const struct lp_build_tgsi_params *params, |
| LLVMValueRef (*outputs)[4]); |
| |
| struct lp_build_nir_context |
| { |
| struct lp_build_context base; |
| struct lp_build_context uint_bld; |
| struct lp_build_context int_bld; |
| struct lp_build_context uint8_bld; |
| struct lp_build_context int8_bld; |
| struct lp_build_context uint16_bld; |
| struct lp_build_context int16_bld; |
| struct lp_build_context dbl_bld; |
| struct lp_build_context uint64_bld; |
| struct lp_build_context int64_bld; |
| |
| LLVMValueRef *ssa_defs; |
| struct hash_table *regs; |
| struct hash_table *vars; |
| |
| nir_shader *shader; |
| |
| void (*load_ubo)(struct lp_build_nir_context *bld_base, |
| unsigned nc, |
| unsigned bit_size, |
| bool offset_is_uniform, |
| LLVMValueRef index, LLVMValueRef offset, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| |
| void (*load_kernel_arg)(struct lp_build_nir_context *bld_base, |
| unsigned nc, |
| unsigned bit_size, |
| unsigned offset_bit_size, |
| bool offset_is_uniform, |
| LLVMValueRef offset, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| |
| void (*load_global)(struct lp_build_nir_context *bld_base, |
| unsigned nc, unsigned bit_size, |
| unsigned offset_bit_size, |
| LLVMValueRef offset, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| |
| void (*store_global)(struct lp_build_nir_context *bld_base, |
| unsigned writemask, |
| unsigned nc, unsigned bit_size, |
| unsigned addr_bit_size, |
| LLVMValueRef addr, LLVMValueRef dst); |
| |
| void (*atomic_global)(struct lp_build_nir_context *bld_base, |
| nir_intrinsic_op op, |
| unsigned addr_bit_size, |
| LLVMValueRef addr, |
| LLVMValueRef val, LLVMValueRef val2, |
| LLVMValueRef *result); |
| |
| /* for SSBO and shared memory */ |
| void (*load_mem)(struct lp_build_nir_context *bld_base, |
| unsigned nc, unsigned bit_size, |
| LLVMValueRef index, LLVMValueRef offset, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| void (*store_mem)(struct lp_build_nir_context *bld_base, |
| unsigned writemask, unsigned nc, unsigned bit_size, |
| LLVMValueRef index, LLVMValueRef offset, LLVMValueRef dst); |
| |
| void (*atomic_mem)(struct lp_build_nir_context *bld_base, |
| nir_intrinsic_op op, |
| LLVMValueRef index, LLVMValueRef offset, |
| LLVMValueRef val, LLVMValueRef val2, |
| LLVMValueRef *result); |
| |
| void (*barrier)(struct lp_build_nir_context *bld_base); |
| |
| void (*image_op)(struct lp_build_nir_context *bld_base, |
| struct lp_img_params *params); |
| void (*image_size)(struct lp_build_nir_context *bld_base, |
| struct lp_sampler_size_query_params *params); |
| LLVMValueRef (*get_ssbo_size)(struct lp_build_nir_context *bld_base, |
| LLVMValueRef index); |
| |
| void (*load_var)(struct lp_build_nir_context *bld_base, |
| nir_variable_mode deref_mode, |
| unsigned num_components, |
| unsigned bit_size, |
| nir_variable *var, |
| unsigned vertex_index, |
| LLVMValueRef indir_vertex_index, |
| unsigned const_index, |
| LLVMValueRef indir_index, |
| LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| void (*store_var)(struct lp_build_nir_context *bld_base, |
| nir_variable_mode deref_mode, |
| unsigned num_components, |
| unsigned bit_size, |
| nir_variable *var, |
| unsigned writemask, |
| LLVMValueRef indir_vertex_index, |
| unsigned const_index, |
| LLVMValueRef indir_index, |
| LLVMValueRef dst); |
| |
| LLVMValueRef (*load_reg)(struct lp_build_nir_context *bld_base, |
| struct lp_build_context *reg_bld, |
| const nir_reg_src *reg, |
| LLVMValueRef indir_src, |
| LLVMValueRef reg_storage); |
| void (*store_reg)(struct lp_build_nir_context *bld_base, |
| struct lp_build_context *reg_bld, |
| const nir_reg_dest *reg, |
| unsigned writemask, |
| LLVMValueRef indir_src, |
| LLVMValueRef reg_storage, |
| LLVMValueRef dst[NIR_MAX_VEC_COMPONENTS]); |
| |
| void (*load_scratch)(struct lp_build_nir_context *bld_base, |
| unsigned nc, unsigned bit_size, |
| LLVMValueRef offset, |
| LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| void (*store_scratch)(struct lp_build_nir_context *bld_base, |
| unsigned writemask, unsigned nc, |
| unsigned bit_size, LLVMValueRef offset, |
| LLVMValueRef val); |
| |
| void (*emit_var_decl)(struct lp_build_nir_context *bld_base, |
| nir_variable *var); |
| |
| void (*tex)(struct lp_build_nir_context *bld_base, |
| struct lp_sampler_params *params); |
| |
| void (*tex_size)(struct lp_build_nir_context *bld_base, |
| struct lp_sampler_size_query_params *params); |
| |
| void (*sysval_intrin)(struct lp_build_nir_context *bld_base, |
| nir_intrinsic_instr *instr, |
| LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]); |
| void (*discard)(struct lp_build_nir_context *bld_base, |
| LLVMValueRef cond); |
| |
| void (*bgnloop)(struct lp_build_nir_context *bld_base); |
| void (*endloop)(struct lp_build_nir_context *bld_base); |
| void (*if_cond)(struct lp_build_nir_context *bld_base, LLVMValueRef cond); |
| void (*else_stmt)(struct lp_build_nir_context *bld_base); |
| void (*endif_stmt)(struct lp_build_nir_context *bld_base); |
| void (*break_stmt)(struct lp_build_nir_context *bld_base); |
| void (*continue_stmt)(struct lp_build_nir_context *bld_base); |
| |
| void (*emit_vertex)(struct lp_build_nir_context *bld_base, uint32_t stream_id); |
| void (*end_primitive)(struct lp_build_nir_context *bld_base, uint32_t stream_id); |
| |
| void (*vote)(struct lp_build_nir_context *bld_base, LLVMValueRef src, nir_intrinsic_instr *instr, LLVMValueRef dst[4]); |
| void (*helper_invocation)(struct lp_build_nir_context *bld_base, LLVMValueRef *dst); |
| |
| void (*interp_at)(struct lp_build_nir_context *bld_base, |
| unsigned num_components, |
| nir_variable *var, |
| bool centroid, bool sample, |
| unsigned const_index, |
| LLVMValueRef indir_index, |
| LLVMValueRef offsets[2], LLVMValueRef dst[4]); |
| // LLVMValueRef main_function |
| }; |
| |
| struct lp_build_nir_soa_context |
| { |
| struct lp_build_nir_context bld_base; |
| |
| /* Builder for scalar elements of shader's data type (float) */ |
| struct lp_build_context elem_bld; |
| struct lp_build_context uint_elem_bld; |
| |
| LLVMValueRef consts_ptr; |
| LLVMValueRef const_sizes_ptr; |
| LLVMValueRef consts[LP_MAX_TGSI_CONST_BUFFERS]; |
| LLVMValueRef consts_sizes[LP_MAX_TGSI_CONST_BUFFERS]; |
| const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS]; |
| LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS]; |
| LLVMValueRef context_ptr; |
| LLVMValueRef thread_data_ptr; |
| |
| LLVMValueRef ssbo_ptr; |
| LLVMValueRef ssbo_sizes_ptr; |
| LLVMValueRef ssbos[LP_MAX_TGSI_SHADER_BUFFERS]; |
| LLVMValueRef ssbo_sizes[LP_MAX_TGSI_SHADER_BUFFERS]; |
| |
| LLVMValueRef shared_ptr; |
| LLVMValueRef scratch_ptr; |
| unsigned scratch_size; |
| |
| const struct lp_build_coro_suspend_info *coro; |
| |
| const struct lp_build_sampler_soa *sampler; |
| const struct lp_build_image_soa *image; |
| |
| const struct lp_build_gs_iface *gs_iface; |
| const struct lp_build_tcs_iface *tcs_iface; |
| const struct lp_build_tes_iface *tes_iface; |
| const struct lp_build_fs_iface *fs_iface; |
| LLVMValueRef emitted_prims_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; |
| LLVMValueRef total_emitted_vertices_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; |
| LLVMValueRef emitted_vertices_vec_ptr[PIPE_MAX_VERTEX_STREAMS]; |
| LLVMValueRef max_output_vertices_vec; |
| struct lp_bld_tgsi_system_values system_values; |
| |
| nir_variable_mode indirects; |
| struct lp_build_mask_context *mask; |
| struct lp_exec_mask exec_mask; |
| |
| /* We allocate/use this array of inputs if (indirects & nir_var_shader_in) is |
| * set. The inputs[] array above is unused then. |
| */ |
| LLVMValueRef inputs_array; |
| |
| LLVMValueRef kernel_args_ptr; |
| unsigned gs_vertex_streams; |
| }; |
| |
| bool |
| lp_build_nir_llvm(struct lp_build_nir_context *bld_base, |
| struct nir_shader *nir); |
| |
| void lp_build_opt_nir(struct nir_shader *nir); |
| |
| static inline LLVMValueRef |
| lp_nir_array_build_gather_values(LLVMBuilderRef builder, |
| LLVMValueRef * values, |
| unsigned value_count) |
| { |
| LLVMTypeRef arr_type = LLVMArrayType(LLVMTypeOf(values[0]), value_count); |
| LLVMValueRef arr = LLVMGetUndef(arr_type); |
| unsigned i; |
| |
| for (i = 0; i < value_count; i++) { |
| arr = LLVMBuildInsertValue(builder, arr, values[i], i, ""); |
| } |
| return arr; |
| } |
| |
| |
| static inline struct lp_build_context *get_int_bld(struct lp_build_nir_context *bld_base, |
| bool is_unsigned, |
| unsigned op_bit_size) |
| { |
| if (is_unsigned) { |
| switch (op_bit_size) { |
| case 64: |
| return &bld_base->uint64_bld; |
| case 32: |
| default: |
| return &bld_base->uint_bld; |
| case 16: |
| return &bld_base->uint16_bld; |
| case 8: |
| return &bld_base->uint8_bld; |
| } |
| } else { |
| switch (op_bit_size) { |
| case 64: |
| return &bld_base->int64_bld; |
| default: |
| case 32: |
| return &bld_base->int_bld; |
| case 16: |
| return &bld_base->int16_bld; |
| case 8: |
| return &bld_base->int8_bld; |
| } |
| } |
| } |
| |
| #endif |