#ifndef BRW_EU_H
#define BRW_EU_H
+#include <stdbool.h>
#include "brw_structs.h"
#include "brw_defines.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3)
#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3)
#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0)
+#define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1)
+#define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2)
+#define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3)
#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1)
+static inline bool brw_is_single_value_swizzle(int swiz)
+{
+ return (swiz == BRW_SWIZZLE_XXXX ||
+ swiz == BRW_SWIZZLE_YYYY ||
+ swiz == BRW_SWIZZLE_ZZZZ ||
+ swiz == BRW_SWIZZLE_WWWW);
+}
#define REG_SIZE (8*4)
};
-struct brw_glsl_label;
-struct brw_glsl_call;
-
-
-
#define BRW_EU_MAX_INSN_STACK 5
-#define BRW_EU_MAX_INSN 10000
struct brw_compile {
- struct brw_instruction store[BRW_EU_MAX_INSN];
+ struct brw_instruction *store;
+ int store_size;
GLuint nr_insn;
+ void *mem_ctx;
+
/* Allow clients to push/pop instruction state:
*/
struct brw_instruction stack[BRW_EU_MAX_INSN_STACK];
+ bool compressed_stack[BRW_EU_MAX_INSN_STACK];
struct brw_instruction *current;
GLuint flag_value;
- GLboolean single_program_flow;
+ bool single_program_flow;
+ bool compressed;
struct brw_context *brw;
- struct brw_glsl_label *first_label; /**< linked list of labels */
- struct brw_glsl_call *first_call; /**< linked list of CALs */
+ /* Control flow stacks:
+ * - if_stack contains IF and ELSE instructions which must be patched
+ * (and popped) once the matching ENDIF instruction is encountered.
+ *
+ * Just store the instruction pointer(an index).
+ */
+ int *if_stack;
+ int if_stack_depth;
+ int if_stack_array_size;
+
+ /**
+ * loop_stack contains the instruction pointers of the starts of loops which
+ * must be patched (and popped) once the matching WHILE instruction is
+ * encountered.
+ */
+ int *loop_stack;
+ /**
+ * pre-gen6, the BREAK and CONT instructions had to tell how many IF/ENDIF
+ * blocks they were popping out of, to fix up the mask stack. This tracks
+ * the IF/ENDIF nesting in each current nested loop level.
+ */
+ int *if_depth_in_loop;
+ int loop_stack_depth;
+ int loop_stack_array_size;
};
-
-void
-brw_save_label(struct brw_compile *c, const char *name, GLuint position);
-
-void
-brw_save_call(struct brw_compile *c, const char *name, GLuint call_pos);
-
-void
-brw_resolve_cals(struct brw_compile *c);
-
-
-
static INLINE int type_sz( GLuint type )
{
switch( type ) {
return reg;
}
+static inline struct brw_reg
+sechalf(struct brw_reg reg)
+{
+ if (reg.vstride)
+ reg.nr++;
+ return reg;
+}
+
static INLINE struct brw_reg suboffset( struct brw_reg reg,
GLuint delta )
{
0);
}
+static INLINE struct brw_reg brw_notification_1_reg(void)
+{
+
+ return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+ BRW_ARF_NOTIFICATION_COUNT,
+ 1,
+ BRW_REGISTER_TYPE_UD,
+ BRW_VERTICAL_STRIDE_0,
+ BRW_WIDTH_1,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XXXX,
+ WRITEMASK_X);
+}
+
static INLINE struct brw_reg brw_flag_reg( void )
{
return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt));
}
+static INLINE struct brw_reg get_element_d( struct brw_reg reg, GLuint elt )
+{
+ return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_D), elt));
+}
+
static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
GLuint x,
GLuint z,
GLuint w)
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
+
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
GLuint mask )
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
reg.dw1.bits.writemask &= mask;
return reg;
}
static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
GLuint mask )
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
reg.dw1.bits.writemask = mask;
return reg;
}
static INLINE struct brw_reg brw_abs( struct brw_reg reg )
{
reg.abs = 1;
+ reg.negate = 0;
return reg;
}
}
/** Do two brw_regs refer to the same register? */
-static INLINE GLboolean
+static INLINE bool
brw_same_reg(struct brw_reg r1, struct brw_reg r2)
{
return r1.file == r2.file && r1.nr == r2.nr;
void brw_set_mask_control( struct brw_compile *p, GLuint value );
void brw_set_saturate( struct brw_compile *p, GLuint value );
void brw_set_access_mode( struct brw_compile *p, GLuint access_mode );
-void brw_set_compression_control( struct brw_compile *p, GLboolean control );
+void brw_set_compression_control(struct brw_compile *p, enum brw_compression c);
void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
+void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse);
void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
+void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
-void brw_init_compile( struct brw_context *, struct brw_compile *p );
+void brw_init_compile(struct brw_context *, struct brw_compile *p,
+ void *mem_ctx);
const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
+struct brw_instruction *brw_next_insn(struct brw_compile *p, GLuint opcode);
+void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn,
+ struct brw_reg dest);
+void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn,
+ struct brw_reg reg);
+
+void gen6_resolve_implied_move(struct brw_compile *p,
+ struct brw_reg *src,
+ GLuint msg_reg_nr);
/* Helpers for regular instructions:
*/
struct brw_reg src0, \
struct brw_reg src1);
+#define ALU3(OP) \
+struct brw_instruction *brw_##OP(struct brw_compile *p, \
+ struct brw_reg dest, \
+ struct brw_reg src0, \
+ struct brw_reg src1, \
+ struct brw_reg src2);
+
+#define ROUND(OP) \
+void brw_##OP(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0);
+
ALU1(MOV)
ALU2(SEL)
ALU1(NOT)
ALU2(MUL)
ALU1(FRC)
ALU1(RNDD)
-ALU1(RNDZ)
ALU2(MAC)
ALU2(MACH)
ALU1(LZD)
ALU2(DP2)
ALU2(LINE)
ALU2(PLN)
+ALU3(MAD)
+
+ROUND(RNDZ)
+ROUND(RNDE)
#undef ALU1
#undef ALU2
-
+#undef ALU3
+#undef ROUND
/* Helpers for SEND instruction:
*/
+void brw_set_sampler_message(struct brw_compile *p,
+ struct brw_instruction *insn,
+ GLuint binding_table_index,
+ GLuint sampler,
+ GLuint msg_type,
+ GLuint response_length,
+ GLuint msg_length,
+ GLuint header_present,
+ GLuint simd_mode,
+ GLuint return_format);
+
+void brw_set_dp_read_message(struct brw_compile *p,
+ struct brw_instruction *insn,
+ GLuint binding_table_index,
+ GLuint msg_control,
+ GLuint msg_type,
+ GLuint target_cache,
+ GLuint msg_length,
+ GLuint response_length);
+
+void brw_set_dp_write_message(struct brw_compile *p,
+ struct brw_instruction *insn,
+ GLuint binding_table_index,
+ GLuint msg_control,
+ GLuint msg_type,
+ GLuint msg_length,
+ bool header_present,
+ GLuint last_render_target,
+ GLuint response_length,
+ GLuint end_of_thread,
+ GLuint send_commit_msg);
+
void brw_urb_WRITE(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
- GLboolean allocate,
- GLboolean used,
+ bool allocate,
+ bool used,
GLuint msg_length,
GLuint response_length,
- GLboolean eot,
- GLboolean writes_complete,
+ bool eot,
+ bool writes_complete,
GLuint offset,
GLuint swizzle);
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
- GLboolean allocate,
- GLboolean used,
- GLuint msg_length,
+ bool allocate,
GLuint response_length,
- GLboolean eot,
- GLboolean writes_complete,
- GLuint offset,
- GLuint swizzle);
+ bool eot);
+
+void brw_svb_write(struct brw_compile *p,
+ struct brw_reg dest,
+ GLuint msg_reg_nr,
+ struct brw_reg src0,
+ GLuint binding_table_index,
+ bool send_commit_msg);
void brw_fb_WRITE(struct brw_compile *p,
- struct brw_reg dest,
+ int dispatch_width,
GLuint msg_reg_nr,
struct brw_reg src0,
GLuint binding_table_index,
GLuint msg_length,
GLuint response_length,
- GLboolean eot);
+ bool eot,
+ bool header_present);
void brw_SAMPLE(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
- GLboolean eot,
GLuint header_present,
- GLuint simd_mode);
+ GLuint simd_mode,
+ GLuint return_format);
void brw_math_16( struct brw_compile *p,
struct brw_reg dest,
GLuint data_type,
GLuint precision );
-void brw_dp_READ_16( struct brw_compile *p,
- struct brw_reg dest,
- GLuint scratch_offset );
-
-void brw_dp_READ_4( struct brw_compile *p,
- struct brw_reg dest,
- GLboolean relAddr,
- GLuint location,
- GLuint bind_table_index );
+void brw_math2(struct brw_compile *p,
+ struct brw_reg dest,
+ GLuint function,
+ struct brw_reg src0,
+ struct brw_reg src1);
+
+void brw_oword_block_read(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg mrf,
+ uint32_t offset,
+ uint32_t bind_table_index);
+
+void brw_oword_block_read_scratch(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg mrf,
+ int num_regs,
+ GLuint offset);
+
+void brw_oword_block_write_scratch(struct brw_compile *p,
+ struct brw_reg mrf,
+ int num_regs,
+ GLuint offset);
+
+void brw_dword_scattered_read(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg mrf,
+ uint32_t bind_table_index);
void brw_dp_READ_4_vs( struct brw_compile *p,
struct brw_reg dest,
- GLuint oword,
- GLboolean relAddr,
- struct brw_reg addrReg,
GLuint location,
GLuint bind_table_index );
-void brw_dp_WRITE_16( struct brw_compile *p,
- struct brw_reg src,
- GLuint scratch_offset );
+void brw_dp_READ_4_vs_relative(struct brw_compile *p,
+ struct brw_reg dest,
+ struct brw_reg addrReg,
+ GLuint offset,
+ GLuint bind_table_index);
/* If/else/endif. Works by manipulating the execution flags on each
* channel.
*/
struct brw_instruction *brw_IF(struct brw_compile *p,
GLuint execute_size);
+struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
+ struct brw_reg src0, struct brw_reg src1);
-struct brw_instruction *brw_ELSE(struct brw_compile *p,
- struct brw_instruction *if_insn);
-
-void brw_ENDIF(struct brw_compile *p,
- struct brw_instruction *if_or_else_insn);
-
+void brw_ELSE(struct brw_compile *p);
+void brw_ENDIF(struct brw_compile *p);
/* DO/WHILE loops:
*/
struct brw_instruction *brw_DO(struct brw_compile *p,
GLuint execute_size);
-struct brw_instruction *brw_WHILE(struct brw_compile *p,
- struct brw_instruction *patch_insn);
+struct brw_instruction *brw_WHILE(struct brw_compile *p);
struct brw_instruction *brw_BREAK(struct brw_compile *p);
struct brw_instruction *brw_CONT(struct brw_compile *p);
+struct brw_instruction *gen6_CONT(struct brw_compile *p);
+struct brw_instruction *gen6_HALT(struct brw_compile *p);
/* Forward jumps:
*/
-void brw_land_fwd_jump(struct brw_compile *p,
- struct brw_instruction *jmp_insn);
+void brw_land_fwd_jump(struct brw_compile *p, int jmp_insn_idx);
void brw_NOP(struct brw_compile *p);
+void brw_WAIT(struct brw_compile *p);
+
/* Special case: there is never a destination, execution size will be
* taken from src0:
*/
struct brw_reg dst,
struct brw_reg src);
-void brw_set_src1( struct brw_instruction *insn,
- struct brw_reg reg );
+void brw_set_src1(struct brw_compile *p,
+ struct brw_instruction *insn,
+ struct brw_reg reg);
+
+void brw_set_uip_jip(struct brw_compile *p);
+uint32_t brw_swap_cmod(uint32_t cmod);
/* brw_optimize.c */
void brw_optimize(struct brw_compile *p);
+void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
+void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
+
+#ifdef __cplusplus
+}
+#endif
#endif