#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"
*/
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
*/
struct lp_bld_tgsi_system_values {
LLVMValueRef instance_id;
LLVMValueRef vertex_id;
+ LLVMValueRef vertex_id_nobase;
LLVMValueRef prim_id;
+ LLVMValueRef basevertex;
};
const struct lp_derivatives *derivs,
LLVMValueRef lod_bias, /* optional */
LLVMValueRef explicit_lod, /* optional */
+ enum lp_sampler_lod_property,
LLVMValueRef *texel);
void
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);
};
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);
+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;
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
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;
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 *,
{
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,
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];
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];
*/
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 */
struct lp_exec_mask exec_mask;
uint num_immediates;
-
+ boolean use_immediates_array;
};
void
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];