llvmpipe: add framebuffer fetching support (v1.1)
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_tgsi.h
index cc4549778a3fbe86a55d83fb2d0da8fa2e7550e4..856cea40c55ebd600deb4a1e2835af2af642c1c4 100644 (file)
@@ -41,6 +41,7 @@
 #include "gallivm/lp_bld_tgsi_action.h"
 #include "gallivm/lp_bld_limits.h"
 #include "gallivm/lp_bld_sample.h"
+#include "gallivm/lp_bld_ir_common.h"
 #include "lp_bld_type.h"
 #include "pipe/p_compiler.h"
 #include "pipe/p_state.h"
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_info.h"
 
-#define LP_CHAN_ALL ~0
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LP_CHAN_ALL ~0u
 
 #define LP_MAX_INSTRUCTIONS 256
 
@@ -56,14 +61,14 @@ struct tgsi_full_declaration;
 struct tgsi_full_immediate;
 struct tgsi_full_instruction;
 struct tgsi_full_src_register;
+struct tgsi_full_dst_register;
 struct tgsi_opcode_info;
 struct tgsi_token;
 struct tgsi_shader_info;
 struct lp_build_mask_context;
 struct gallivm_state;
 struct lp_derivatives;
-struct lp_build_tgsi_gs_iface;
-
+struct lp_build_gs_iface;
 
 enum lp_build_tex_modifier {
    LP_BLD_TEX_MODIFIER_NONE = 0,
@@ -161,11 +166,26 @@ struct lp_tgsi_info
  */
 struct lp_bld_tgsi_system_values {
    LLVMValueRef instance_id;
+   LLVMValueRef base_instance;
    LLVMValueRef vertex_id;
    LLVMValueRef vertex_id_nobase;
    LLVMValueRef prim_id;
    LLVMValueRef basevertex;
    LLVMValueRef invocation_id;
+   LLVMValueRef draw_id;
+   LLVMValueRef thread_id;
+   LLVMValueRef block_id;
+   LLVMValueRef grid_size;
+   LLVMValueRef front_facing;
+   LLVMValueRef work_dim;
+   LLVMValueRef block_size;
+   LLVMValueRef tess_coord;
+   LLVMValueRef tess_outer;
+   LLVMValueRef tess_inner;
+   LLVMValueRef vertices_in;
+   LLVMValueRef sample_id;
+   LLVMValueRef sample_pos;
+   LLVMValueRef sample_mask_in;
 };
 
 
@@ -190,21 +210,14 @@ struct lp_build_sampler_soa
    void
    (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
                        struct gallivm_state *gallivm,
-                       struct lp_type type,
-                       unsigned unit,
-                       unsigned target,
-                       LLVMValueRef context_ptr,
-                       boolean need_nr_mips,
-                       enum lp_sampler_lod_property,
-                       LLVMValueRef explicit_lod, /* optional */
-                       LLVMValueRef *sizes_out);
+                       const struct lp_sampler_size_query_params *params);
 };
 
 
 struct lp_build_sampler_aos
 {
    LLVMValueRef
-   (*emit_fetch_texel)( struct lp_build_sampler_aos *sampler,
+   (*emit_fetch_texel)( const struct lp_build_sampler_aos *sampler,
                         struct lp_build_context *bld,
                         unsigned target, /* TGSI_TEXTURE_* */
                         unsigned unit,
@@ -213,28 +226,72 @@ struct lp_build_sampler_aos
                         enum lp_build_tex_modifier modifier);
 };
 
+struct lp_img_params;
+
+struct lp_build_image_soa
+{
+   void
+   (*destroy)( struct lp_build_image_soa *image );
+
+   void
+   (*emit_op)(const struct lp_build_image_soa *image,
+              struct gallivm_state *gallivm,
+              const struct lp_img_params *params);
+
+   void
+   (*emit_size_query)( const struct lp_build_image_soa *sampler,
+                       struct gallivm_state *gallivm,
+                       const struct lp_sampler_size_query_params *params);
+};
+
+struct lp_build_fs_iface;
+struct lp_build_fs_iface {
+   LLVMValueRef (*interp_fn)(const struct lp_build_fs_iface *iface,
+                             struct lp_build_context *bld,
+                             unsigned attrib, unsigned chan,
+                             bool centroid, bool sample,
+                             LLVMValueRef indir_index, LLVMValueRef offsets[2]);
+
+   void (*fb_fetch)(const struct lp_build_fs_iface *iface,
+                    struct lp_build_context *bld,
+                    unsigned cbuf,
+                    LLVMValueRef result[4]);
+};
 
 void
 lp_build_tgsi_info(const struct tgsi_token *tokens,
                    struct lp_tgsi_info *info);
 
 
+struct lp_build_tgsi_params {
+   struct lp_type type;
+   struct lp_build_mask_context *mask;
+   LLVMValueRef consts_ptr;
+   LLVMValueRef const_sizes_ptr;
+   const struct lp_bld_tgsi_system_values *system_values;
+   const LLVMValueRef (*inputs)[4];
+   LLVMValueRef context_ptr;
+   LLVMValueRef thread_data_ptr;
+   const struct lp_build_sampler_soa *sampler;
+   const struct tgsi_shader_info *info;
+   const struct lp_build_gs_iface *gs_iface;
+   const struct lp_build_tcs_iface *tcs_iface;
+   const struct lp_build_tes_iface *tes_iface;
+   LLVMValueRef ssbo_ptr;
+   LLVMValueRef ssbo_sizes_ptr;
+   const struct lp_build_image_soa *image;
+   LLVMValueRef shared_ptr;
+   const struct lp_build_coro_suspend_info *coro;
+   LLVMValueRef kernel_args;
+   const struct lp_build_fs_iface *fs_iface;
+   unsigned gs_vertex_streams;
+};
+
 void
 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 const_sizes_ptr,
-                  const struct lp_bld_tgsi_system_values *system_values,
-                  const LLVMValueRef (*inputs)[4],
-                  LLVMValueRef (*outputs)[4],
-                  LLVMValueRef context_ptr,
-                  LLVMValueRef thread_data_ptr,
-                  struct lp_build_sampler_soa *sampler,
-                  const struct tgsi_shader_info *info,
-                  const struct lp_build_tgsi_gs_iface *gs_iface);
-
+                  const struct lp_build_tgsi_params *params,
+                  LLVMValueRef (*outputs)[4]);
 
 void
 lp_build_tgsi_aos(struct gallivm_state *gallivm,
@@ -244,71 +301,10 @@ lp_build_tgsi_aos(struct gallivm_state *gallivm,
                   LLVMValueRef consts_ptr,
                   const LLVMValueRef *inputs,
                   LLVMValueRef *outputs,
-                  struct lp_build_sampler_aos *sampler,
+                  const struct lp_build_sampler_aos *sampler,
                   const struct tgsi_shader_info *info);
 
 
-enum lp_exec_mask_break_type {
-   LP_EXEC_MASK_BREAK_TYPE_LOOP,
-   LP_EXEC_MASK_BREAK_TYPE_SWITCH
-};
-
-
-struct lp_exec_mask {
-   struct lp_build_context *bld;
-
-   boolean has_mask;
-   boolean ret_in_main;
-
-   LLVMTypeRef int_vec_type;
-
-   LLVMValueRef exec_mask;
-
-   LLVMValueRef ret_mask;
-   LLVMValueRef cond_mask;
-   LLVMValueRef switch_mask;         /* current switch exec mask */
-   LLVMValueRef cont_mask;
-   LLVMValueRef break_mask;
-
-   struct function_ctx {
-      int pc;
-      LLVMValueRef ret_mask;
-
-      LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
-      int cond_stack_size;
-
-      /* keep track if break belongs to switch or loop */
-      enum lp_exec_mask_break_type break_type_stack[LP_MAX_TGSI_NESTING];
-      enum lp_exec_mask_break_type break_type;
-
-      struct {
-         LLVMValueRef switch_val;
-         LLVMValueRef switch_mask;
-         LLVMValueRef switch_mask_default;
-         boolean switch_in_default;
-         unsigned switch_pc;
-      } switch_stack[LP_MAX_TGSI_NESTING];
-      int switch_stack_size;
-      LLVMValueRef switch_val;
-      LLVMValueRef switch_mask_default; /* reverse of switch mask used for default */
-      boolean switch_in_default;        /* if switch exec is currently in default */
-      unsigned switch_pc;               /* when used points to default or endswitch-1 */
-
-      LLVMValueRef loop_limiter;
-      LLVMBasicBlockRef loop_block;
-      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;
-
-   } *function_stack;
-   int function_stack_size;
-};
-
 struct lp_build_tgsi_inst_list
 {
    struct tgsi_full_instruction *instructions;
@@ -332,6 +328,14 @@ typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *,
                                         enum tgsi_opcode_type,
                                         unsigned);
 
+typedef void (*lp_build_emit_store_reg_fn)(struct lp_build_tgsi_context *,
+                              enum tgsi_opcode_type,
+                              const struct tgsi_full_dst_register *,
+                              unsigned,
+                              unsigned,
+                              LLVMValueRef,
+                              LLVMValueRef);
+
 struct lp_build_tgsi_context
 {
    struct lp_build_context base;
@@ -340,6 +344,10 @@ struct lp_build_tgsi_context
    struct lp_build_context int_bld;
 
    struct lp_build_context dbl_bld;
+
+   struct lp_build_context uint64_bld;
+   struct lp_build_context int64_bld;
+
    /** This array stores functions that are used to transform TGSI opcodes to
      * LLVM instructions.
      */
@@ -357,6 +365,7 @@ struct lp_build_tgsi_context
    const struct tgsi_shader_info *info;
 
    lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT];
+   lp_build_emit_store_reg_fn emit_store_reg_funcs[TGSI_FILE_COUNT];
 
    LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *,
                          LLVMValueRef, unsigned, unsigned, unsigned, unsigned);
@@ -369,6 +378,7 @@ struct lp_build_tgsi_context
    void (*emit_store)(struct lp_build_tgsi_context *,
                       const struct tgsi_full_instruction *,
                       const struct tgsi_opcode_info *,
+                      unsigned index,
                       LLVMValueRef dst[4]);
 
    void (*emit_declaration)(struct lp_build_tgsi_context *,
@@ -396,6 +406,12 @@ struct lp_build_tgsi_context
      */
    void (*emit_prologue)(struct lp_build_tgsi_context*);
 
+   /** This function allows the user to insert some instructions after
+     * declarations section, but before any other code.
+     * It is optional and does not need to be implemented.
+     */
+   void (*emit_prologue_post_decl)(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
@@ -405,27 +421,81 @@ struct lp_build_tgsi_context
    void (*emit_epilogue)(struct lp_build_tgsi_context*);
 };
 
-struct lp_build_tgsi_gs_iface
+struct lp_build_gs_iface
 {
-   LLVMValueRef (*fetch_input)(const struct lp_build_tgsi_gs_iface *gs_iface,
-                               struct lp_build_tgsi_context * bld_base,
+   LLVMValueRef (*fetch_input)(const struct lp_build_gs_iface *gs_iface,
+                               struct lp_build_context * bld,
                                boolean is_vindex_indirect,
                                LLVMValueRef vertex_index,
                                boolean is_aindex_indirect,
                                LLVMValueRef attrib_index,
                                LLVMValueRef swizzle_index);
-   void (*emit_vertex)(const struct lp_build_tgsi_gs_iface *gs_iface,
-                       struct lp_build_tgsi_context * bld_base,
+   void (*emit_vertex)(const struct lp_build_gs_iface *gs_iface,
+                       struct lp_build_context * bld,
                        LLVMValueRef (*outputs)[4],
-                       LLVMValueRef emitted_vertices_vec);
-   void (*end_primitive)(const struct lp_build_tgsi_gs_iface *gs_iface,
-                         struct lp_build_tgsi_context * bld_base,
+                       LLVMValueRef emitted_vertices_vec,
+                       LLVMValueRef mask_vec, LLVMValueRef stream_id);
+   void (*end_primitive)(const struct lp_build_gs_iface *gs_iface,
+                         struct lp_build_context * bld,
+                         LLVMValueRef total_emitted_vertices_vec,
                          LLVMValueRef verts_per_prim_vec,
-                         LLVMValueRef emitted_prims_vec);
-   void (*gs_epilogue)(const struct lp_build_tgsi_gs_iface *gs_iface,
-                       struct lp_build_tgsi_context * bld_base,
+                         LLVMValueRef emitted_prims_vec,
+                         LLVMValueRef mask_vec, unsigned stream);
+   void (*gs_epilogue)(const struct lp_build_gs_iface *gs_iface,
                        LLVMValueRef total_emitted_vertices_vec,
-                       LLVMValueRef emitted_prims_vec);
+                       LLVMValueRef emitted_prims_vec, unsigned stream);
+};
+
+struct lp_build_tcs_iface
+{
+   void (*emit_prologue)(struct lp_build_context * bld);
+   void (*emit_epilogue)(struct lp_build_context * bld);
+   void (*emit_barrier)(struct lp_build_context *bld_base);
+
+   void (*emit_store_output)(const struct lp_build_tcs_iface *tcs_iface,
+                             struct lp_build_context * bld,
+                             unsigned name,
+                             boolean is_vindex_indirect,
+                             LLVMValueRef vertex_index,
+                             boolean is_aindex_indirect,
+                             LLVMValueRef attrib_index,
+                             LLVMValueRef swizzle_index,
+                             LLVMValueRef value,
+                             LLVMValueRef mask_vec);
+
+   LLVMValueRef (*emit_fetch_input)(const struct lp_build_tcs_iface *tcs_iface,
+                                    struct lp_build_context * bld,
+                                    boolean is_vindex_indirect,
+                                    LLVMValueRef vertex_index,
+                                    boolean is_aindex_indirect,
+                                    LLVMValueRef attrib_index,
+                                    LLVMValueRef swizzle_index);
+
+   LLVMValueRef (*emit_fetch_output)(const struct lp_build_tcs_iface *tcs_iface,
+                                    struct lp_build_context * bld,
+                                    boolean is_vindex_indirect,
+                                    LLVMValueRef vertex_index,
+                                    boolean is_aindex_indirect,
+                                    LLVMValueRef attrib_index,
+                                    LLVMValueRef swizzle_index,
+                                    uint32_t name);
+};
+
+struct lp_build_tes_iface
+{
+   LLVMValueRef (*fetch_vertex_input)(const struct lp_build_tes_iface *tes_iface,
+                                      struct lp_build_context * bld,
+                                      boolean is_vindex_indirect,
+                                      LLVMValueRef vertex_index,
+                                      boolean is_aindex_indirect,
+                                      LLVMValueRef attrib_index,
+                                      LLVMValueRef swizzle_index);
+
+   LLVMValueRef (*fetch_patch_input)(const struct lp_build_tes_iface *tes_iface,
+                                     struct lp_build_context * bld,
+                                     boolean is_aindex_indirect,
+                                     LLVMValueRef attrib_index,
+                                     LLVMValueRef swizzle_index);
 };
 
 struct lp_build_tgsi_soa_context
@@ -435,7 +505,10 @@ struct lp_build_tgsi_soa_context
    /* Builder for scalar elements of shader's data type (float) */
    struct lp_build_context elem_bld;
 
-   const struct lp_build_tgsi_gs_iface *gs_iface;
+   const struct lp_build_gs_iface *gs_iface;
+   const struct lp_build_tcs_iface *tcs_iface;
+   const struct lp_build_tes_iface *tes_iface;
+
    LLVMValueRef emitted_prims_vec_ptr;
    LLVMValueRef total_emitted_vertices_vec_ptr;
    LLVMValueRef emitted_vertices_vec_ptr;
@@ -450,14 +523,23 @@ struct lp_build_tgsi_soa_context
    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;
+
+   const struct lp_build_coro_suspend_info *coro;
+
    const struct lp_build_sampler_soa *sampler;
+   const struct lp_build_image_soa *image;
 
    struct tgsi_declaration_sampler_view sv[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
    LLVMValueRef immediates[LP_MAX_INLINED_IMMEDIATES][TGSI_NUM_CHANNELS];
    LLVMValueRef temps[LP_MAX_INLINED_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.
@@ -544,14 +626,13 @@ struct lp_build_tgsi_aos_context
    const LLVMValueRef *inputs;
    LLVMValueRef *outputs;
 
-   struct lp_build_sampler_aos *sampler;
+   const struct lp_build_sampler_aos *sampler;
 
    struct tgsi_declaration_sampler_view sv[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
    LLVMValueRef immediates[LP_MAX_INLINED_IMMEDIATES];
    LLVMValueRef temps[LP_MAX_INLINED_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.
@@ -643,6 +724,13 @@ lp_build_tgsi_inst_llvm(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_full_instruction *inst);
 
+LLVMValueRef
+lp_build_emit_fetch_src(
+   struct lp_build_tgsi_context *bld_base,
+   const struct tgsi_full_src_register *reg,
+   enum tgsi_opcode_type stype,
+   const unsigned chan_index);
+
 LLVMValueRef
 lp_build_emit_fetch(
    struct lp_build_tgsi_context *bld_base,
@@ -663,4 +751,8 @@ lp_build_tgsi_llvm(
    struct lp_build_tgsi_context * bld_base,
    const struct tgsi_token *tokens);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LP_BLD_TGSI_H */