freedreno/ir3: fix register usage calculations
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_tgsi.h
index 6e65e126d689cda23ca312228e83484cac08a558..b411f05674d2e3c2fda56d616c4f71161974c8b1 100644 (file)
@@ -40,6 +40,7 @@
 #include "gallivm/lp_bld.h"
 #include "gallivm/lp_bld_tgsi_action.h"
 #include "gallivm/lp_bld_limits.h"
+#include "gallivm/lp_bld_sample.h"
 #include "lp_bld_type.h"
 #include "pipe/p_compiler.h"
 #include "pipe/p_state.h"
@@ -61,6 +62,7 @@ struct tgsi_shader_info;
 struct lp_build_mask_context;
 struct gallivm_state;
 struct lp_derivatives;
+struct lp_build_tgsi_gs_iface;
 
 
 enum lp_build_tex_modifier {
@@ -124,6 +126,12 @@ struct lp_tgsi_info
     */
    unsigned indirect_textures:1;
 
+   /*
+    * Whether any of the texture (sample) ocpodes use different sampler
+    * and sampler view unit.
+    */
+   unsigned sampler_texture_units_different:1;
+
    /*
     * Whether any immediate values are outside the range of 0 and 1
     */
@@ -154,6 +162,9 @@ struct lp_tgsi_info
 struct lp_bld_tgsi_system_values {
    LLVMValueRef instance_id;
    LLVMValueRef vertex_id;
+   LLVMValueRef vertex_id_nobase;
+   LLVMValueRef prim_id;
+   LLVMValueRef basevertex;
 };
 
 
@@ -182,6 +193,7 @@ struct lp_build_sampler_soa
                         const struct lp_derivatives *derivs,
                         LLVMValueRef lod_bias, /* optional */
                         LLVMValueRef explicit_lod, /* optional */
+                        enum lp_sampler_lod_property,
                         LLVMValueRef *texel);
 
    void
@@ -189,7 +201,9 @@ struct lp_build_sampler_soa
                        struct gallivm_state *gallivm,
                        struct lp_type type,
                        unsigned unit,
+                       unsigned target,
                        boolean need_nr_mips,
+                       enum lp_sampler_lod_property,
                        LLVMValueRef explicit_lod, /* optional */
                        LLVMValueRef *sizes_out);
 };
@@ -219,12 +233,13 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
                   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 *pos,
                   const LLVMValueRef (*inputs)[4],
                   LLVMValueRef (*outputs)[4],
                   struct lp_build_sampler_soa *sampler,
-                  const struct tgsi_shader_info *info);
+                  const struct tgsi_shader_info *info,
+                  const struct lp_build_tgsi_gs_iface *gs_iface);
 
 
 void
@@ -239,6 +254,12 @@ lp_build_tgsi_aos(struct gallivm_state *gallivm,
                   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;
 
@@ -247,31 +268,51 @@ struct lp_exec_mask {
 
    LLVMTypeRef int_vec_type;
 
-   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
-   int cond_stack_size;
-   LLVMValueRef cond_mask;
+   LLVMValueRef exec_mask;
 
-   LLVMBasicBlockRef loop_block;
+   LLVMValueRef ret_mask;
+   LLVMValueRef cond_mask;
+   LLVMValueRef switch_mask;         /* current switch exec mask */
    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 {
+   struct function_ctx {
       int pc;
       LLVMValueRef ret_mask;
-   } call_stack[LP_MAX_TGSI_NESTING];
-   int call_stack_size;
 
-   LLVMValueRef exec_mask;
-   LLVMValueRef loop_limiter;
+      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
@@ -286,7 +327,7 @@ 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);
+   const struct tgsi_full_instruction *inst_to_add);
 
 
 struct lp_build_tgsi_context;
@@ -322,6 +363,11 @@ struct lp_build_tgsi_context
    LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *,
                          LLVMValueRef, unsigned, unsigned, unsigned, unsigned);
 
+
+   void (*emit_debug)(struct lp_build_tgsi_context *,
+                      const struct tgsi_full_instruction *,
+                      const struct tgsi_opcode_info *);
+
    void (*emit_store)(struct lp_build_tgsi_context *,
                       const struct tgsi_full_instruction *,
                       const struct tgsi_opcode_info *,
@@ -361,6 +407,29 @@ struct lp_build_tgsi_context
    void (*emit_epilogue)(struct lp_build_tgsi_context*);
 };
 
+struct lp_build_tgsi_gs_iface
+{
+   LLVMValueRef (*fetch_input)(const struct lp_build_tgsi_gs_iface *gs_iface,
+                               struct lp_build_tgsi_context * bld_base,
+                               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,
+                       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 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 total_emitted_vertices_vec,
+                       LLVMValueRef emitted_prims_vec);
+};
+
 struct lp_build_tgsi_soa_context
 {
    struct lp_build_tgsi_context bld_base;
@@ -368,8 +437,16 @@ 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;
+   LLVMValueRef emitted_prims_vec_ptr;
+   LLVMValueRef total_emitted_vertices_vec_ptr;
+   LLVMValueRef emitted_vertices_vec_ptr;
+   LLVMValueRef max_output_vertices_vec;
+
    LLVMValueRef consts_ptr;
-   const LLVMValueRef *pos;
+   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];
 
@@ -377,8 +454,8 @@ struct lp_build_tgsi_soa_context
 
    struct tgsi_declaration_sampler_view sv[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
-   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][TGSI_NUM_CHANNELS];
-   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][TGSI_NUM_CHANNELS];
+   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];
 
@@ -400,6 +477,12 @@ struct lp_build_tgsi_soa_context
     */
    LLVMValueRef inputs_array;
 
+   /* We allocate/use this array of temps if (1 << TGSI_FILE_IMMEDIATE) is
+    * set in the indirect_files field.
+    */
+   LLVMValueRef imms_array;
+
+
    struct lp_bld_tgsi_system_values system_values;
 
    /** bitmask indicating which register files are accessed indirectly */
@@ -409,7 +492,7 @@ struct lp_build_tgsi_soa_context
    struct lp_exec_mask exec_mask;
 
    uint num_immediates;
-
+   boolean use_immediates_array;
 };
 
 void
@@ -463,8 +546,10 @@ struct lp_build_tgsi_aos_context
 
    struct lp_build_sampler_aos *sampler;
 
-   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES];
-   LLVMValueRef temps[LP_MAX_TGSI_TEMPS];
+   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];