X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Ftgsi%2Ftgsi_ureg.h;h=99908d9ce052a9ff7e26e0abc555f1258a088545;hb=bd1cab1168b30502c8371a3e837b4fc2e39c23bf;hp=b1297a25a94d929ec522a2bdc48d92e9b268f9b6;hpb=a5f44cc8c2ce0916809ce5da5a2490ad000ef099;p=mesa.git diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index b1297a25a94..99908d9ce05 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -36,6 +36,7 @@ extern "C" { #endif +struct pipe_screen; struct ureg_program; struct pipe_stream_output_info; @@ -62,6 +63,7 @@ struct ureg_src int IndirectIndex : 16; /* SINT */ int DimensionIndex : 16; /* SINT */ int DimIndIndex : 16; /* SINT */ + unsigned ArrayID : 10; /* UINT */ }; /* Very similar to a tgsi_dst_register, removing unsupported fields @@ -71,25 +73,36 @@ struct ureg_src */ struct ureg_dst { - unsigned File : 4; /* TGSI_FILE_ */ - unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ - unsigned Indirect : 1; /* BOOL */ - unsigned Saturate : 1; /* BOOL */ - unsigned Predicate : 1; - unsigned PredNegate : 1; /* BOOL */ - unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */ - int Index : 16; /* SINT */ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ + unsigned Indirect : 1; /* BOOL */ + unsigned DimIndirect : 1; /* BOOL */ + unsigned Dimension : 1; /* BOOL */ + unsigned Saturate : 1; /* BOOL */ + unsigned Predicate : 1; + unsigned PredNegate : 1; /* BOOL */ + unsigned PredSwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleW : 2; /* TGSI_SWIZZLE_ */ + int Index : 16; /* SINT */ int IndirectIndex : 16; /* SINT */ + unsigned IndirectFile : 4; /* TGSI_FILE_ */ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ + unsigned DimIndFile : 4; /* TGSI_FILE_ */ + unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */ + int DimensionIndex : 16; /* SINT */ + int DimIndIndex : 16; /* SINT */ + unsigned ArrayID : 10; /* UINT */ }; struct pipe_context; struct ureg_program * -ureg_create( unsigned processor ); +ureg_create(unsigned processor); + +struct ureg_program * +ureg_create_with_screen(unsigned processor, struct pipe_screen *screen); const struct tgsi_token * ureg_finalize( struct ureg_program * ); @@ -101,6 +114,8 @@ ureg_create_shader( struct ureg_program *, struct pipe_context *pipe, const struct pipe_stream_output_info *so ); +void +ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor); /* Alternately, return the built token stream and hand ownership of * that memory to the caller: @@ -109,6 +124,12 @@ const struct tgsi_token * ureg_get_tokens( struct ureg_program *ureg, unsigned *nr_tokens ); +/* + * Returns the number of currently declared outputs. + */ +unsigned +ureg_get_nr_outputs( const struct ureg_program *ureg ); + /* Free the tokens created by ureg_get_tokens() */ void ureg_free_tokens( const struct tgsi_token *tokens ); @@ -121,7 +142,7 @@ ureg_destroy( struct ureg_program * ); /*********************************************************************** * Convenience routine: */ -static INLINE void * +static inline void * ureg_create_shader_with_so_and_destroy( struct ureg_program *p, struct pipe_context *pipe, const struct pipe_stream_output_info *so ) @@ -131,7 +152,7 @@ ureg_create_shader_with_so_and_destroy( struct ureg_program *p, return result; } -static INLINE void * +static inline void * ureg_create_shader_and_destroy( struct ureg_program *p, struct pipe_context *pipe ) { @@ -144,47 +165,36 @@ ureg_create_shader_and_destroy( struct ureg_program *p, */ void -ureg_property_gs_input_prim(struct ureg_program *ureg, - unsigned input_prim); - -void -ureg_property_gs_output_prim(struct ureg_program *ureg, - unsigned output_prim); - -void -ureg_property_gs_max_vertices(struct ureg_program *ureg, - unsigned max_vertices); - -void -ureg_property_fs_coord_origin(struct ureg_program *ureg, - unsigned fs_coord_origin); - -void -ureg_property_fs_coord_pixel_center(struct ureg_program *ureg, - unsigned fs_coord_pixel_center); - -void -ureg_property_fs_color0_writes_all_cbufs(struct ureg_program *ureg, - unsigned fs_color0_writes_all_cbufs); - -void -ureg_property_fs_depth_layout(struct ureg_program *ureg, - unsigned fs_depth_layout); +ureg_property(struct ureg_program *ureg, unsigned name, unsigned value); /*********************************************************************** * Build shader declarations: */ +struct ureg_src +ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp_mode, + unsigned cylindrical_wrap, + unsigned interp_location, + unsigned index, + unsigned usage_mask, + unsigned array_id, + unsigned array_size); + struct ureg_src ureg_DECL_fs_input_cyl_centroid(struct ureg_program *, unsigned semantic_name, unsigned semantic_index, unsigned interp_mode, unsigned cylindrical_wrap, - unsigned centroid); + unsigned interp_location, + unsigned array_id, + unsigned array_size); -static INLINE struct ureg_src +static inline struct ureg_src ureg_DECL_fs_input_cyl(struct ureg_program *ureg, unsigned semantic_name, unsigned semantic_index, @@ -196,10 +206,10 @@ ureg_DECL_fs_input_cyl(struct ureg_program *ureg, semantic_index, interp_mode, cylindrical_wrap, - 0); + 0, 0, 1); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_DECL_fs_input(struct ureg_program *ureg, unsigned semantic_name, unsigned semantic_index, @@ -209,7 +219,7 @@ ureg_DECL_fs_input(struct ureg_program *ureg, semantic_name, semantic_index, interp_mode, - 0, 0); + 0, 0, 0, 1); } struct ureg_src @@ -217,33 +227,66 @@ ureg_DECL_vs_input( struct ureg_program *, unsigned index ); struct ureg_src -ureg_DECL_gs_input(struct ureg_program *, - unsigned index, - unsigned semantic_name, - unsigned semantic_index); +ureg_DECL_input_layout(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned index, + unsigned usage_mask, + unsigned array_id, + unsigned array_size); + +struct ureg_src +ureg_DECL_input(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned array_id, + unsigned array_size); struct ureg_src ureg_DECL_system_value(struct ureg_program *, - unsigned index, unsigned semantic_name, unsigned semantic_index); struct ureg_dst -ureg_DECL_output_masked( struct ureg_program *, - unsigned semantic_name, - unsigned semantic_index, - unsigned usage_mask ); +ureg_DECL_output_layout(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned streams, + unsigned index, + unsigned usage_mask, + unsigned array_id, + unsigned array_size); + +struct ureg_dst +ureg_DECL_output_masked(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned usage_mask, + unsigned array_id, + unsigned array_size); struct ureg_dst -ureg_DECL_output( struct ureg_program *, - unsigned semantic_name, - unsigned semantic_index ); +ureg_DECL_output(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index); + +struct ureg_dst +ureg_DECL_output_array(struct ureg_program *ureg, + unsigned semantic_name, + unsigned semantic_index, + unsigned array_id, + unsigned array_size); struct ureg_src ureg_DECL_immediate( struct ureg_program *, const float *v, unsigned nr ); +struct ureg_src +ureg_DECL_immediate_f64( struct ureg_program *, + const double *v, + unsigned nr ); + struct ureg_src ureg_DECL_immediate_uint( struct ureg_program *, const unsigned *v, @@ -259,6 +302,16 @@ ureg_DECL_immediate_int( struct ureg_program *, const int *v, unsigned nr ); +struct ureg_src +ureg_DECL_immediate_uint64( struct ureg_program *, + const uint64_t *v, + unsigned nr ); + +struct ureg_src +ureg_DECL_immediate_int64( struct ureg_program *, + const int64_t *v, + unsigned nr ); + void ureg_DECL_constant2D(struct ureg_program *ureg, unsigned first, @@ -272,6 +325,22 @@ ureg_DECL_constant( struct ureg_program *, struct ureg_dst ureg_DECL_temporary( struct ureg_program * ); +/** + * Emit a temporary with the LOCAL declaration flag set. For use when + * the register value is not required to be preserved across + * subroutine boundaries. + */ +struct ureg_dst +ureg_DECL_local_temporary( struct ureg_program * ); + +/** + * Declare "size" continuous temporary registers. + */ +struct ureg_dst +ureg_DECL_array_temporary( struct ureg_program *, + unsigned size, + boolean local ); + void ureg_release_temporary( struct ureg_program *ureg, struct ureg_dst tmp ); @@ -300,8 +369,21 @@ ureg_DECL_sampler_view(struct ureg_program *, unsigned return_type_z, unsigned return_type_w ); +struct ureg_src +ureg_DECL_image(struct ureg_program *ureg, + unsigned index, + unsigned target, + unsigned format, + boolean wr, + boolean raw); -static INLINE struct ureg_src +struct ureg_src +ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic); + +struct ureg_src +ureg_DECL_memory(struct ureg_program *ureg, unsigned memory_type); + +static inline struct ureg_src ureg_imm4f( struct ureg_program *ureg, float a, float b, float c, float d) @@ -314,7 +396,7 @@ ureg_imm4f( struct ureg_program *ureg, return ureg_DECL_immediate( ureg, v, 4 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm3f( struct ureg_program *ureg, float a, float b, float c) @@ -326,7 +408,7 @@ ureg_imm3f( struct ureg_program *ureg, return ureg_DECL_immediate( ureg, v, 3 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm2f( struct ureg_program *ureg, float a, float b) { @@ -336,7 +418,7 @@ ureg_imm2f( struct ureg_program *ureg, return ureg_DECL_immediate( ureg, v, 2 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm1f( struct ureg_program *ureg, float a) { @@ -345,7 +427,7 @@ ureg_imm1f( struct ureg_program *ureg, return ureg_DECL_immediate( ureg, v, 1 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm4u( struct ureg_program *ureg, unsigned a, unsigned b, unsigned c, unsigned d) @@ -358,7 +440,7 @@ ureg_imm4u( struct ureg_program *ureg, return ureg_DECL_immediate_uint( ureg, v, 4 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm3u( struct ureg_program *ureg, unsigned a, unsigned b, unsigned c) @@ -370,7 +452,7 @@ ureg_imm3u( struct ureg_program *ureg, return ureg_DECL_immediate_uint( ureg, v, 3 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm2u( struct ureg_program *ureg, unsigned a, unsigned b) { @@ -380,14 +462,14 @@ ureg_imm2u( struct ureg_program *ureg, return ureg_DECL_immediate_uint( ureg, v, 2 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm1u( struct ureg_program *ureg, unsigned a) { return ureg_DECL_immediate_uint( ureg, &a, 1 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm4i( struct ureg_program *ureg, int a, int b, int c, int d) @@ -400,7 +482,7 @@ ureg_imm4i( struct ureg_program *ureg, return ureg_DECL_immediate_int( ureg, v, 4 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm3i( struct ureg_program *ureg, int a, int b, int c) @@ -412,7 +494,7 @@ ureg_imm3i( struct ureg_program *ureg, return ureg_DECL_immediate_int( ureg, v, 3 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm2i( struct ureg_program *ureg, int a, int b) { @@ -422,13 +504,23 @@ ureg_imm2i( struct ureg_program *ureg, return ureg_DECL_immediate_int( ureg, v, 2 ); } -static INLINE struct ureg_src +static inline struct ureg_src ureg_imm1i( struct ureg_program *ureg, int a) { return ureg_DECL_immediate_int( ureg, &a, 1 ); } +/* Where the destination register has a valid file, but an empty + * writemask. + */ +static inline boolean +ureg_dst_is_empty( struct ureg_dst dst ) +{ + return dst.File != TGSI_FILE_NULL && + dst.WriteMask == 0; +} + /*********************************************************************** * Functions for patching up labels */ @@ -479,12 +571,15 @@ ureg_tex_insn(struct ureg_program *ureg, void -ureg_label_insn(struct ureg_program *ureg, - unsigned opcode, - const struct ureg_src *src, - unsigned nr_src, - unsigned *label); - +ureg_memory_insn(struct ureg_program *ureg, + unsigned opcode, + const struct ureg_dst *dst, + unsigned nr_dst, + const struct ureg_src *src, + unsigned nr_src, + unsigned qualifier, + unsigned texture, + unsigned format); /*********************************************************************** * Internal instruction helpers, don't call these directly: @@ -522,6 +617,13 @@ void ureg_emit_texture_offset(struct ureg_program *ureg, const struct tgsi_texture_offset *offset); +void +ureg_emit_memory(struct ureg_program *ureg, + unsigned insn_token, + unsigned qualifier, + unsigned texture, + unsigned format); + void ureg_emit_dst( struct ureg_program *ureg, struct ureg_dst dst ); @@ -536,45 +638,47 @@ ureg_fixup_insn_size(struct ureg_program *ureg, #define OP00( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg ) \ +static inline void ureg_##op( struct ureg_program *ureg ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - FALSE, \ - FALSE, \ - FALSE, \ - TGSI_SWIZZLE_X, \ - TGSI_SWIZZLE_Y, \ - TGSI_SWIZZLE_Z, \ - TGSI_SWIZZLE_W, \ - 0, \ - 0).insn_token; \ - ureg_fixup_insn_size( ureg, insn ); \ + struct ureg_emit_insn_result insn; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + FALSE, \ + FALSE, \ + FALSE, \ + TGSI_SWIZZLE_X, \ + TGSI_SWIZZLE_Y, \ + TGSI_SWIZZLE_Z, \ + TGSI_SWIZZLE_W, \ + 0, \ + 0); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP01( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_src src ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - FALSE, \ - FALSE, \ - FALSE, \ - TGSI_SWIZZLE_X, \ - TGSI_SWIZZLE_Y, \ - TGSI_SWIZZLE_Z, \ - TGSI_SWIZZLE_W, \ - 0, \ - 1).insn_token; \ + struct ureg_emit_insn_result insn; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + FALSE, \ + FALSE, \ + FALSE, \ + TGSI_SWIZZLE_X, \ + TGSI_SWIZZLE_Y, \ + TGSI_SWIZZLE_Z, \ + TGSI_SWIZZLE_W, \ + 0, \ + 1); \ ureg_emit_src( ureg, src ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP00_LBL( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ unsigned *label_token ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ @@ -595,7 +699,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ } #define OP01_LBL( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_src src, \ unsigned *label_token ) \ { \ @@ -618,74 +722,83 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ } #define OP10( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 0).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 0); \ ureg_emit_dst( ureg, dst ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP11( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ struct ureg_src src ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 1).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 1); \ ureg_emit_dst( ureg, dst ); \ ureg_emit_src( ureg, src ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP12( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ struct ureg_src src0, \ struct ureg_src src1 ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 2).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 2); \ ureg_emit_dst( ureg, dst ); \ ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src1 ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP12_TEX( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ unsigned target, \ struct ureg_src src0, \ @@ -693,6 +806,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ { \ unsigned opcode = TGSI_OPCODE_##op; \ struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ insn = ureg_emit_insn(ureg, \ opcode, \ dst.Saturate, \ @@ -711,34 +826,97 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ ureg_fixup_insn_size( ureg, insn.insn_token ); \ } +#define OP12_SAMPLE( op ) \ +static inline void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned target = TGSI_TEXTURE_UNKNOWN; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 2); \ + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ +} + #define OP13( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ struct ureg_src src0, \ struct ureg_src src1, \ struct ureg_src src2 ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 3).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 3); \ ureg_emit_dst( ureg, dst ); \ ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src1 ); \ ureg_emit_src( ureg, src2 ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ +} + +#define OP13_SAMPLE( op ) \ +static inline void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned target = TGSI_TEXTURE_UNKNOWN; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 3); \ + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP14_TEX( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ unsigned target, \ struct ureg_src src0, \ @@ -748,6 +926,8 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ { \ unsigned opcode = TGSI_OPCODE_##op; \ struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ insn = ureg_emit_insn(ureg, \ opcode, \ dst.Saturate, \ @@ -768,9 +948,42 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ ureg_fixup_insn_size( ureg, insn.insn_token ); \ } +#define OP14_SAMPLE( op ) \ +static inline void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2, \ + struct ureg_src src3 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned target = TGSI_TEXTURE_UNKNOWN; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 4); \ + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_emit_src( ureg, src3 ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ +} + #define OP14( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ struct ureg_src src0, \ struct ureg_src src1, \ @@ -778,28 +991,31 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ struct ureg_src src3 ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 4).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 4); \ ureg_emit_dst( ureg, dst ); \ ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src1 ); \ ureg_emit_src( ureg, src2 ); \ ureg_emit_src( ureg, src3 ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } #define OP15( op ) \ -static INLINE void ureg_##op( struct ureg_program *ureg, \ +static inline void ureg_##op( struct ureg_program *ureg, \ struct ureg_dst dst, \ struct ureg_src src0, \ struct ureg_src src1, \ @@ -808,26 +1024,63 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ struct ureg_src src4 ) \ { \ unsigned opcode = TGSI_OPCODE_##op; \ - unsigned insn = ureg_emit_insn(ureg, \ - opcode, \ - dst.Saturate, \ - dst.Predicate, \ - dst.PredNegate, \ - dst.PredSwizzleX, \ - dst.PredSwizzleY, \ - dst.PredSwizzleZ, \ - dst.PredSwizzleW, \ - 1, \ - 5).insn_token; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 5); \ ureg_emit_dst( ureg, dst ); \ ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src1 ); \ ureg_emit_src( ureg, src2 ); \ ureg_emit_src( ureg, src3 ); \ ureg_emit_src( ureg, src4 ); \ - ureg_fixup_insn_size( ureg, insn ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ } +#define OP15_SAMPLE( op ) \ +static inline void ureg_##op( struct ureg_program *ureg, \ + struct ureg_dst dst, \ + struct ureg_src src0, \ + struct ureg_src src1, \ + struct ureg_src src2, \ + struct ureg_src src3, \ + struct ureg_src src4 ) \ +{ \ + unsigned opcode = TGSI_OPCODE_##op; \ + unsigned target = TGSI_TEXTURE_UNKNOWN; \ + struct ureg_emit_insn_result insn; \ + if (ureg_dst_is_empty(dst)) \ + return; \ + insn = ureg_emit_insn(ureg, \ + opcode, \ + dst.Saturate, \ + dst.Predicate, \ + dst.PredNegate, \ + dst.PredSwizzleX, \ + dst.PredSwizzleY, \ + dst.PredSwizzleZ, \ + dst.PredSwizzleW, \ + 1, \ + 5); \ + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \ + ureg_emit_dst( ureg, dst ); \ + ureg_emit_src( ureg, src0 ); \ + ureg_emit_src( ureg, src1 ); \ + ureg_emit_src( ureg, src2 ); \ + ureg_emit_src( ureg, src3 ); \ + ureg_emit_src( ureg, src4 ); \ + ureg_fixup_insn_size( ureg, insn.insn_token ); \ +} /* Use a template include to generate a correctly-typed ureg_OP() * function for each TGSI opcode: @@ -838,7 +1091,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \ /*********************************************************************** * Inline helpers for manipulating register structs: */ -static INLINE struct ureg_src +static inline struct ureg_src ureg_negate( struct ureg_src reg ) { assert(reg.File != TGSI_FILE_NULL); @@ -846,7 +1099,7 @@ ureg_negate( struct ureg_src reg ) return reg; } -static INLINE struct ureg_src +static inline struct ureg_src ureg_abs( struct ureg_src reg ) { assert(reg.File != TGSI_FILE_NULL); @@ -855,7 +1108,7 @@ ureg_abs( struct ureg_src reg ) return reg; } -static INLINE struct ureg_src +static inline struct ureg_src ureg_swizzle( struct ureg_src reg, int x, int y, int z, int w ) { @@ -877,13 +1130,13 @@ ureg_swizzle( struct ureg_src reg, return reg; } -static INLINE struct ureg_src +static inline struct ureg_src ureg_scalar( struct ureg_src reg, int x ) { return ureg_swizzle(reg, x, x, x, x); } -static INLINE struct ureg_dst +static inline struct ureg_dst ureg_writemask( struct ureg_dst reg, unsigned writemask ) { @@ -892,7 +1145,7 @@ ureg_writemask( struct ureg_dst reg, return reg; } -static INLINE struct ureg_dst +static inline struct ureg_dst ureg_saturate( struct ureg_dst reg ) { assert(reg.File != TGSI_FILE_NULL); @@ -900,7 +1153,7 @@ ureg_saturate( struct ureg_dst reg ) return reg; } -static INLINE struct ureg_dst +static inline struct ureg_dst ureg_predicate(struct ureg_dst reg, boolean negate, unsigned swizzle_x, @@ -918,18 +1171,19 @@ ureg_predicate(struct ureg_dst reg, return reg; } -static INLINE struct ureg_dst +static inline struct ureg_dst ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr ) { assert(reg.File != TGSI_FILE_NULL); - assert(addr.File == TGSI_FILE_ADDRESS); + assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY); reg.Indirect = 1; + reg.IndirectFile = addr.File; reg.IndirectIndex = addr.Index; reg.IndirectSwizzle = addr.SwizzleX; return reg; } -static INLINE struct ureg_src +static inline struct ureg_src ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) { assert(reg.File != TGSI_FILE_NULL); @@ -941,7 +1195,17 @@ ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) return reg; } -static INLINE struct ureg_src +static inline struct ureg_dst +ureg_dst_dimension( struct ureg_dst reg, int index ) +{ + assert(reg.File != TGSI_FILE_NULL); + reg.Dimension = 1; + reg.DimIndirect = 0; + reg.DimensionIndex = index; + return reg; +} + +static inline struct ureg_src ureg_src_dimension( struct ureg_src reg, int index ) { assert(reg.File != TGSI_FILE_NULL); @@ -951,8 +1215,21 @@ ureg_src_dimension( struct ureg_src reg, int index ) return reg; } +static inline struct ureg_dst +ureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr, + int index ) +{ + assert(reg.File != TGSI_FILE_NULL); + reg.Dimension = 1; + reg.DimIndirect = 1; + reg.DimensionIndex = index; + reg.DimIndFile = addr.File; + reg.DimIndIndex = addr.Index; + reg.DimIndSwizzle = addr.SwizzleX; + return reg; +} -static INLINE struct ureg_src +static inline struct ureg_src ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, int index ) { @@ -966,15 +1243,71 @@ ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, return reg; } -static INLINE struct ureg_dst +static inline struct ureg_src +ureg_src_array_offset(struct ureg_src reg, int offset) +{ + reg.Index += offset; + return reg; +} + +static inline struct ureg_dst +ureg_dst_array_offset( struct ureg_dst reg, int offset ) +{ + reg.Index += offset; + return reg; +} + +static inline struct ureg_dst +ureg_dst_array_register(unsigned file, + unsigned index, + unsigned array_id) +{ + struct ureg_dst dst; + + dst.File = file; + dst.WriteMask = TGSI_WRITEMASK_XYZW; + dst.Indirect = 0; + dst.IndirectFile = TGSI_FILE_NULL; + dst.IndirectIndex = 0; + dst.IndirectSwizzle = 0; + dst.Saturate = 0; + dst.Predicate = 0; + dst.PredNegate = 0; + dst.PredSwizzleX = TGSI_SWIZZLE_X; + dst.PredSwizzleY = TGSI_SWIZZLE_Y; + dst.PredSwizzleZ = TGSI_SWIZZLE_Z; + dst.PredSwizzleW = TGSI_SWIZZLE_W; + dst.Index = index; + dst.Dimension = 0; + dst.DimensionIndex = 0; + dst.DimIndirect = 0; + dst.DimIndFile = TGSI_FILE_NULL; + dst.DimIndIndex = 0; + dst.DimIndSwizzle = 0; + dst.ArrayID = array_id; + + return dst; +} + +static inline struct ureg_dst +ureg_dst_register(unsigned file, + unsigned index) +{ + return ureg_dst_array_register(file, index, 0); +} + +static inline struct ureg_dst ureg_dst( struct ureg_src src ) { struct ureg_dst dst; - assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS); + assert(!src.Indirect || + (src.IndirectFile == TGSI_FILE_ADDRESS || + src.IndirectFile == TGSI_FILE_TEMPORARY)); dst.File = src.File; dst.WriteMask = TGSI_WRITEMASK_XYZW; + dst.IndirectFile = src.IndirectFile; dst.Indirect = src.Indirect; dst.IndirectIndex = src.IndirectIndex; dst.IndirectSwizzle = src.IndirectSwizzle; @@ -986,13 +1319,21 @@ ureg_dst( struct ureg_src src ) dst.PredSwizzleZ = TGSI_SWIZZLE_Z; dst.PredSwizzleW = TGSI_SWIZZLE_W; dst.Index = src.Index; + dst.Dimension = src.Dimension; + dst.DimensionIndex = src.DimensionIndex; + dst.DimIndirect = src.DimIndirect; + dst.DimIndFile = src.DimIndFile; + dst.DimIndIndex = src.DimIndIndex; + dst.DimIndSwizzle = src.DimIndSwizzle; + dst.ArrayID = src.ArrayID; return dst; } -static INLINE struct ureg_src -ureg_src_register(unsigned file, - unsigned index) +static inline struct ureg_src +ureg_src_array_register(unsigned file, + unsigned index, + unsigned array_id) { struct ureg_src src; @@ -1014,11 +1355,19 @@ ureg_src_register(unsigned file, src.DimIndFile = TGSI_FILE_NULL; src.DimIndIndex = 0; src.DimIndSwizzle = 0; + src.ArrayID = array_id; return src; } -static INLINE struct ureg_src +static inline struct ureg_src +ureg_src_register(unsigned file, + unsigned index) +{ + return ureg_src_array_register(file, index, 0); +} + +static inline struct ureg_src ureg_src( struct ureg_dst dst ) { struct ureg_src src; @@ -1029,25 +1378,26 @@ ureg_src( struct ureg_dst dst ) src.SwizzleZ = TGSI_SWIZZLE_Z; src.SwizzleW = TGSI_SWIZZLE_W; src.Indirect = dst.Indirect; - src.IndirectFile = TGSI_FILE_ADDRESS; + src.IndirectFile = dst.IndirectFile; src.IndirectIndex = dst.IndirectIndex; src.IndirectSwizzle = dst.IndirectSwizzle; src.Absolute = 0; src.Index = dst.Index; src.Negate = 0; - src.Dimension = 0; - src.DimensionIndex = 0; - src.DimIndirect = 0; - src.DimIndFile = TGSI_FILE_NULL; - src.DimIndIndex = 0; - src.DimIndSwizzle = 0; + src.Dimension = dst.Dimension; + src.DimensionIndex = dst.DimensionIndex; + src.DimIndirect = dst.DimIndirect; + src.DimIndFile = dst.DimIndFile; + src.DimIndIndex = dst.DimIndIndex; + src.DimIndSwizzle = dst.DimIndSwizzle; + src.ArrayID = dst.ArrayID; return src; } -static INLINE struct ureg_dst +static inline struct ureg_dst ureg_dst_undef( void ) { struct ureg_dst dst; @@ -1055,6 +1405,7 @@ ureg_dst_undef( void ) dst.File = TGSI_FILE_NULL; dst.WriteMask = 0; dst.Indirect = 0; + dst.IndirectFile = TGSI_FILE_NULL; dst.IndirectIndex = 0; dst.IndirectSwizzle = 0; dst.Saturate = 0; @@ -1065,11 +1416,18 @@ ureg_dst_undef( void ) dst.PredSwizzleZ = TGSI_SWIZZLE_Z; dst.PredSwizzleW = TGSI_SWIZZLE_W; dst.Index = 0; + dst.Dimension = 0; + dst.DimensionIndex = 0; + dst.DimIndirect = 0; + dst.DimIndFile = TGSI_FILE_NULL; + dst.DimIndIndex = 0; + dst.DimIndSwizzle = 0; + dst.ArrayID = 0; return dst; } -static INLINE struct ureg_src +static inline struct ureg_src ureg_src_undef( void ) { struct ureg_src src; @@ -1092,17 +1450,18 @@ ureg_src_undef( void ) src.DimIndFile = TGSI_FILE_NULL; src.DimIndIndex = 0; src.DimIndSwizzle = 0; + src.ArrayID = 0; return src; } -static INLINE boolean +static inline boolean ureg_src_is_undef( struct ureg_src src ) { return src.File == TGSI_FILE_NULL; } -static INLINE boolean +static inline boolean ureg_dst_is_undef( struct ureg_dst dst ) { return dst.File == TGSI_FILE_NULL;