X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fgallivm%2Flp_bld_tgsi.h;h=b799900bfd7e209ea9f910c0ea1ec3028084cbf2;hb=4a72d859b4f8d0444eb7f38606d59d7ddc9ea8fa;hp=a4d3b750c3cfa36f8d75d781024e287297ea7dc5;hpb=dbf3a15313eed930a3d8fdde12e457259c43651b;p=mesa.git diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index a4d3b750c3c..b799900bfd7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -1,5 +1,6 @@ /************************************************************************** * + * Copyright 2011-2012 Advanced Micro Devices, Inc. * Copyright 2009 VMware, Inc. * All Rights Reserved. * @@ -30,22 +31,35 @@ * TGSI to LLVM IR translation. * * @author Jose Fonseca + * @author Tom Stellard */ #ifndef LP_BLD_TGSI_H #define LP_BLD_TGSI_H #include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_tgsi_action.h" +#include "gallivm/lp_bld_limits.h" +#include "lp_bld_type.h" #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_info.h" +#define LP_CHAN_ALL ~0 +#define LP_MAX_INSTRUCTIONS 256 + +struct tgsi_full_declaration; +struct tgsi_full_immediate; +struct tgsi_full_instruction; +struct tgsi_full_src_register; +struct tgsi_opcode_info; struct tgsi_token; struct tgsi_shader_info; -struct lp_type; -struct lp_build_context; struct lp_build_mask_context; +struct gallivm_state; enum lp_build_tex_modifier { @@ -141,7 +155,7 @@ struct lp_build_sampler_soa void (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler, - LLVMBuilderRef builder, + struct gallivm_state *gallivm, struct lp_type type, unsigned unit, unsigned num_coords, @@ -174,11 +188,12 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, void -lp_build_tgsi_soa(LLVMBuilderRef builder, +lp_build_tgsi_soa(struct gallivm_state *gallivm, const struct tgsi_token *tokens, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], @@ -187,7 +202,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, void -lp_build_tgsi_aos(LLVMBuilderRef builder, +lp_build_tgsi_aos(struct gallivm_state *gallivm, const struct tgsi_token *tokens, struct lp_type type, const unsigned char swizzles[4], @@ -198,4 +213,336 @@ lp_build_tgsi_aos(LLVMBuilderRef builder, const struct tgsi_shader_info *info); +LLVMValueRef +lp_build_system_values_array(struct gallivm_state *gallivm, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing); + + +struct lp_exec_mask { + struct lp_build_context *bld; + + boolean has_mask; + + LLVMTypeRef int_vec_type; + + LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING]; + int cond_stack_size; + LLVMValueRef cond_mask; + + LLVMBasicBlockRef loop_block; + LLVMValueRef cont_mask; + LLVMValueRef break_mask; + LLVMValueRef break_var; + struct { + LLVMBasicBlockRef loop_block; + LLVMValueRef cont_mask; + LLVMValueRef break_mask; + LLVMValueRef break_var; + } loop_stack[LP_MAX_TGSI_NESTING]; + int loop_stack_size; + + LLVMValueRef ret_mask; + struct { + int pc; + LLVMValueRef ret_mask; + } call_stack[LP_MAX_TGSI_NESTING]; + int call_stack_size; + + LLVMValueRef exec_mask; +}; + +struct lp_build_tgsi_inst_list +{ + struct tgsi_full_instruction *instructions; + uint max_instructions; + uint num_instructions; +}; + +unsigned lp_bld_tgsi_list_init(struct lp_build_tgsi_context * bld_base); + + +unsigned lp_bld_tgsi_add_instruction( + struct lp_build_tgsi_context * bld_base, + struct tgsi_full_instruction *inst_to_add); + + +struct lp_build_tgsi_context; + + +typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *, + const struct tgsi_full_src_register *, + enum tgsi_opcode_type, + unsigned); + +struct lp_build_tgsi_context +{ + struct lp_build_context base; + + struct lp_build_context uint_bld; + struct lp_build_context int_bld; + + /** This array stores functions that are used to transform TGSI opcodes to + * LLVM instructions. + */ + struct lp_build_tgsi_action op_actions[TGSI_OPCODE_LAST]; + + /* TGSI_OPCODE_RSQ is defined as 1 / sqrt( abs(src0.x) ), rsq_action + * should compute 1 / sqrt (src0.x) */ + struct lp_build_tgsi_action rsq_action; + + const struct tgsi_shader_info *info; + + lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT]; + + LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *, + LLVMValueRef, unsigned, unsigned, unsigned, unsigned); + + void (*emit_store)(struct lp_build_tgsi_context *, + const struct tgsi_full_instruction *, + const struct tgsi_opcode_info *, + LLVMValueRef dst[4]); + + void (*emit_declaration)(struct lp_build_tgsi_context *, + const struct tgsi_full_declaration *decl); + + void (*emit_immediate)(struct lp_build_tgsi_context *, + const struct tgsi_full_immediate *imm); + + + /* Allow the user to store data in this structure rather than passing it + * to every function. */ + void * userdata; + + boolean soa; + + int pc; + + struct tgsi_full_instruction *instructions; + uint max_instructions; + uint num_instructions; + + /** This function allows the user to insert some instructions at the + * beginning of the program. It is optional and does not need to be + * implemented. + */ + void (*emit_prologue)(struct lp_build_tgsi_context*); + + /** This function allows the user to insert some instructions at the end of + * the program. This callback is intended to be used for emitting + * instructions to handle the export for the output registers, but it can + * be used for any purpose. Implementing this function is optiona, but + * recommended. + */ + void (*emit_epilogue)(struct lp_build_tgsi_context*); +}; + +struct lp_build_tgsi_soa_context +{ + struct lp_build_tgsi_context bld_base; + + /* Builder for scalar elements of shader's data type (float) */ + struct lp_build_context elem_bld; + + LLVMValueRef consts_ptr; + const LLVMValueRef *pos; + const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS]; + LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS]; + + const struct lp_build_sampler_soa *sampler; + + LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][TGSI_NUM_CHANNELS]; + LLVMValueRef temps[LP_MAX_TGSI_TEMPS][TGSI_NUM_CHANNELS]; + LLVMValueRef addr[LP_MAX_TGSI_ADDRS][TGSI_NUM_CHANNELS]; + LLVMValueRef preds[LP_MAX_TGSI_PREDS][TGSI_NUM_CHANNELS]; + + /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is + * set in the indirect_files field. + * The temps[] array above is unused then. + */ + LLVMValueRef temps_array; + + /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is + * set in the indirect_files field. + * The outputs[] array above is unused then. + */ + LLVMValueRef outputs_array; + + /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is + * set in the indirect_files field. + * The inputs[] array above is unused then. + */ + LLVMValueRef inputs_array; + + LLVMValueRef system_values_array; + + /** bitmask indicating which register files are accessed indirectly */ + unsigned indirect_files; + + struct lp_build_mask_context *mask; + struct lp_exec_mask exec_mask; + + uint num_immediates; + +}; + +void +lp_emit_declaration_soa( + struct lp_build_tgsi_context *bld, + const struct tgsi_full_declaration *decl); + +void lp_emit_immediate_soa( + struct lp_build_tgsi_context *bld_base, + const struct tgsi_full_immediate *imm); + +boolean +lp_emit_instruction_soa( + struct lp_build_tgsi_soa_context *bld, + const struct tgsi_full_instruction *inst, + const struct tgsi_opcode_info *info); + + +LLVMValueRef +lp_get_temp_ptr_soa( + struct lp_build_tgsi_soa_context *bld, + unsigned index, + unsigned chan); + +LLVMValueRef +lp_get_output_ptr( + struct lp_build_tgsi_soa_context *bld, + unsigned index, + unsigned chan); + +struct lp_build_tgsi_aos_context +{ + struct lp_build_tgsi_context bld_base; + + /* Builder for integer masks and indices */ + struct lp_build_context int_bld; + + /* + * AoS swizzle used: + * - swizzles[0] = red index + * - swizzles[1] = green index + * - swizzles[2] = blue index + * - swizzles[3] = alpha index + */ + unsigned char swizzles[4]; + unsigned char inv_swizzles[4]; + + LLVMValueRef consts_ptr; + const LLVMValueRef *inputs; + LLVMValueRef *outputs; + + struct lp_build_sampler_aos *sampler; + + LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES]; + LLVMValueRef temps[LP_MAX_TGSI_TEMPS]; + LLVMValueRef addr[LP_MAX_TGSI_ADDRS]; + LLVMValueRef preds[LP_MAX_TGSI_PREDS]; + + /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is + * set in the indirect_files field. + * The temps[] array above is unused then. + */ + LLVMValueRef temps_array; + + /** bitmask indicating which register files are accessed indirectly */ + unsigned indirect_files; + +}; + +static INLINE struct lp_build_tgsi_soa_context * +lp_soa_context(struct lp_build_tgsi_context *bld_base) +{ + return (struct lp_build_tgsi_soa_context *)bld_base; +} + +static INLINE struct lp_build_tgsi_aos_context * +lp_aos_context(struct lp_build_tgsi_context *bld_base) +{ + return (struct lp_build_tgsi_aos_context *)bld_base; +} + +void +lp_emit_declaration_aos( + struct lp_build_tgsi_aos_context *bld, + const struct tgsi_full_declaration *decl); + + +boolean +lp_emit_instruction_aos( + struct lp_build_tgsi_aos_context *bld, + const struct tgsi_full_instruction *inst, + const struct tgsi_opcode_info *info, + int *pc); + +void +lp_emit_store_aos( + struct lp_build_tgsi_aos_context *bld, + const struct tgsi_full_instruction *inst, + unsigned index, + LLVMValueRef value); + +void lp_build_fetch_args( + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data); + +LLVMValueRef +lp_build_tgsi_inst_llvm_aos( + struct lp_build_tgsi_context * bld_base, + const struct tgsi_full_instruction *inst); + +void +lp_build_tgsi_intrinsic( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data); + +LLVMValueRef +lp_build_emit_llvm( + struct lp_build_tgsi_context *bld_base, + unsigned tgsi_opcode, + struct lp_build_emit_data * emit_data); + +LLVMValueRef +lp_build_emit_llvm_unary( + struct lp_build_tgsi_context *bld_base, + unsigned tgsi_opcode, + LLVMValueRef arg0); + +LLVMValueRef +lp_build_emit_llvm_binary( + struct lp_build_tgsi_context *bld_base, + unsigned tgsi_opcode, + LLVMValueRef arg0, + LLVMValueRef arg1); + +LLVMValueRef +lp_build_emit_llvm_ternary( + struct lp_build_tgsi_context *bld_base, + unsigned tgsi_opcode, + LLVMValueRef arg0, + LLVMValueRef arg1, + LLVMValueRef arg2); + +boolean +lp_build_tgsi_inst_llvm( + struct lp_build_tgsi_context * bld_base, + const struct tgsi_full_instruction *inst); + +LLVMValueRef +lp_build_emit_fetch( + struct lp_build_tgsi_context *bld_base, + const struct tgsi_full_instruction *inst, + unsigned src_op, + const unsigned chan_index); + +boolean +lp_build_tgsi_llvm( + struct lp_build_tgsi_context * bld_base, + const struct tgsi_token *tokens); + #endif /* LP_BLD_TGSI_H */