Path: blob/21.2-virgl/src/gallium/auxiliary/tgsi/tgsi_ureg.h
4565 views
/**************************************************************************1*2* Copyright 2009 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#ifndef TGSI_UREG_H28#define TGSI_UREG_H2930#include "pipe/p_defines.h"31#include "pipe/p_format.h"32#include "pipe/p_compiler.h"33#include "pipe/p_shader_tokens.h"34#include "util/u_debug.h"3536#ifdef __cplusplus37extern "C" {38#endif3940struct pipe_screen;41struct ureg_program;42struct pipe_stream_output_info;43struct shader_info;4445/* Almost a tgsi_src_register, but we need to pull in the Absolute46* flag from the _ext token. Indirect flag always implies ADDR[0].47*/48struct ureg_src49{50unsigned File : 4; /* TGSI_FILE_ */51unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */52unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */53unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */54unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */55unsigned Indirect : 1; /* BOOL */56unsigned DimIndirect : 1; /* BOOL */57unsigned Dimension : 1; /* BOOL */58unsigned Absolute : 1; /* BOOL */59unsigned Negate : 1; /* BOOL */60unsigned IndirectFile : 4; /* TGSI_FILE_ */61unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */62unsigned DimIndFile : 4; /* TGSI_FILE_ */63unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */64int Index : 16; /* SINT */65int IndirectIndex : 16; /* SINT */66int DimensionIndex : 16; /* SINT */67int DimIndIndex : 16; /* SINT */68unsigned ArrayID : 10; /* UINT */69};7071/* Very similar to a tgsi_dst_register, removing unsupported fields72* and adding a Saturate flag. It's easier to push saturate into the73* destination register than to try and create a _SAT variant of each74* instruction function.75*/76struct ureg_dst77{78unsigned File : 4; /* TGSI_FILE_ */79unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */80unsigned Indirect : 1; /* BOOL */81unsigned DimIndirect : 1; /* BOOL */82unsigned Dimension : 1; /* BOOL */83unsigned Saturate : 1; /* BOOL */84unsigned Invariant : 1; /* BOOL */85int Index : 16; /* SINT */86int IndirectIndex : 16; /* SINT */87unsigned IndirectFile : 4; /* TGSI_FILE_ */88int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */89unsigned DimIndFile : 4; /* TGSI_FILE_ */90unsigned DimIndSwizzle : 2; /* TGSI_SWIZZLE_ */91int DimensionIndex : 16; /* SINT */92int DimIndIndex : 16; /* SINT */93unsigned ArrayID : 10; /* UINT */94};9596struct pipe_context;9798struct ureg_program *99ureg_create(enum pipe_shader_type processor);100101struct ureg_program *102ureg_create_with_screen(enum pipe_shader_type processor,103struct pipe_screen *screen);104105const struct tgsi_token *106ureg_finalize( struct ureg_program * );107108/* Create and return a shader:109*/110void *111ureg_create_shader( struct ureg_program *,112struct pipe_context *pipe,113const struct pipe_stream_output_info *so );114115void116ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor);117118/* Alternately, return the built token stream and hand ownership of119* that memory to the caller:120*/121const struct tgsi_token *122ureg_get_tokens( struct ureg_program *ureg,123unsigned *nr_tokens );124125/*126* Returns the number of currently declared outputs.127*/128unsigned129ureg_get_nr_outputs( const struct ureg_program *ureg );130131132/* Free the tokens created by ureg_get_tokens() */133void ureg_free_tokens( const struct tgsi_token *tokens );134135136void137ureg_destroy( struct ureg_program * );138139140/***********************************************************************141* Convenience routine:142*/143static inline void *144ureg_create_shader_with_so_and_destroy( struct ureg_program *p,145struct pipe_context *pipe,146const struct pipe_stream_output_info *so )147{148void *result = ureg_create_shader( p, pipe, so );149ureg_destroy( p );150return result;151}152153static inline void *154ureg_create_shader_and_destroy( struct ureg_program *p,155struct pipe_context *pipe )156{157return ureg_create_shader_with_so_and_destroy(p, pipe, NULL);158}159160161/***********************************************************************162* Build shader properties:163*/164165void166ureg_property(struct ureg_program *ureg, unsigned name, unsigned value);167168169/***********************************************************************170* Build shader declarations:171*/172173struct ureg_src174ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *,175enum tgsi_semantic semantic_name,176unsigned semantic_index,177enum tgsi_interpolate_mode interp_mode,178unsigned cylindrical_wrap,179enum tgsi_interpolate_loc interp_location,180unsigned index,181unsigned usage_mask,182unsigned array_id,183unsigned array_size);184185struct ureg_src186ureg_DECL_fs_input_cyl_centroid(struct ureg_program *,187enum tgsi_semantic semantic_name,188unsigned semantic_index,189enum tgsi_interpolate_mode interp_mode,190unsigned cylindrical_wrap,191enum tgsi_interpolate_loc interp_location,192unsigned array_id,193unsigned array_size);194195static inline struct ureg_src196ureg_DECL_fs_input_cyl(struct ureg_program *ureg,197enum tgsi_semantic semantic_name,198unsigned semantic_index,199enum tgsi_interpolate_mode interp_mode,200unsigned cylindrical_wrap)201{202return ureg_DECL_fs_input_cyl_centroid(ureg,203semantic_name,204semantic_index,205interp_mode,206cylindrical_wrap,207TGSI_INTERPOLATE_LOC_CENTER, 0, 1);208}209210static inline struct ureg_src211ureg_DECL_fs_input(struct ureg_program *ureg,212enum tgsi_semantic semantic_name,213unsigned semantic_index,214enum tgsi_interpolate_mode interp_mode)215{216return ureg_DECL_fs_input_cyl_centroid(ureg,217semantic_name,218semantic_index,219interp_mode,2200, TGSI_INTERPOLATE_LOC_CENTER, 0, 1);221}222223struct ureg_src224ureg_DECL_vs_input( struct ureg_program *,225unsigned index );226227struct ureg_src228ureg_DECL_input_layout(struct ureg_program *,229enum tgsi_semantic semantic_name,230unsigned semantic_index,231unsigned index,232unsigned usage_mask,233unsigned array_id,234unsigned array_size);235236struct ureg_src237ureg_DECL_input(struct ureg_program *,238enum tgsi_semantic semantic_name,239unsigned semantic_index,240unsigned array_id,241unsigned array_size);242243struct ureg_src244ureg_DECL_system_value(struct ureg_program *,245enum tgsi_semantic semantic_name,246unsigned semantic_index);247248struct ureg_dst249ureg_DECL_output_layout(struct ureg_program *,250enum tgsi_semantic semantic_name,251unsigned semantic_index,252unsigned streams,253unsigned index,254unsigned usage_mask,255unsigned array_id,256unsigned array_size,257boolean invariant);258259struct ureg_dst260ureg_DECL_output_masked(struct ureg_program *,261enum tgsi_semantic semantic_name,262unsigned semantic_index,263unsigned usage_mask,264unsigned array_id,265unsigned array_size);266267struct ureg_dst268ureg_DECL_output(struct ureg_program *,269enum tgsi_semantic semantic_name,270unsigned semantic_index);271272struct ureg_dst273ureg_DECL_output_array(struct ureg_program *ureg,274enum tgsi_semantic semantic_name,275unsigned semantic_index,276unsigned array_id,277unsigned array_size);278279struct ureg_src280ureg_DECL_immediate( struct ureg_program *,281const float *v,282unsigned nr );283284struct ureg_src285ureg_DECL_immediate_f64( struct ureg_program *,286const double *v,287unsigned nr );288289struct ureg_src290ureg_DECL_immediate_uint( struct ureg_program *,291const unsigned *v,292unsigned nr );293294struct ureg_src295ureg_DECL_immediate_block_uint( struct ureg_program *,296const unsigned *v,297unsigned nr );298299struct ureg_src300ureg_DECL_immediate_int( struct ureg_program *,301const int *v,302unsigned nr );303304struct ureg_src305ureg_DECL_immediate_uint64( struct ureg_program *,306const uint64_t *v,307unsigned nr );308309struct ureg_src310ureg_DECL_immediate_int64( struct ureg_program *,311const int64_t *v,312unsigned nr );313314void315ureg_DECL_constant2D(struct ureg_program *ureg,316unsigned first,317unsigned last,318unsigned index2D);319320struct ureg_src321ureg_DECL_constant( struct ureg_program *,322unsigned index );323324void325ureg_DECL_hw_atomic(struct ureg_program *ureg,326unsigned first,327unsigned last,328unsigned buffer_id,329unsigned array_id);330331struct ureg_dst332ureg_DECL_temporary( struct ureg_program * );333334/**335* Emit a temporary with the LOCAL declaration flag set. For use when336* the register value is not required to be preserved across337* subroutine boundaries.338*/339struct ureg_dst340ureg_DECL_local_temporary( struct ureg_program * );341342/**343* Declare "size" continuous temporary registers.344*/345struct ureg_dst346ureg_DECL_array_temporary( struct ureg_program *,347unsigned size,348boolean local );349350void351ureg_release_temporary( struct ureg_program *ureg,352struct ureg_dst tmp );353354struct ureg_dst355ureg_DECL_address( struct ureg_program * );356357/* Supply an index to the sampler declaration as this is the hook to358* the external pipe_sampler state. Users of this function probably359* don't want just any sampler, but a specific one which they've set360* up state for in the context.361*/362struct ureg_src363ureg_DECL_sampler( struct ureg_program *,364unsigned index );365366struct ureg_src367ureg_DECL_sampler_view(struct ureg_program *,368unsigned index,369enum tgsi_texture_type target,370enum tgsi_return_type return_type_x,371enum tgsi_return_type return_type_y,372enum tgsi_return_type return_type_z,373enum tgsi_return_type return_type_w );374375struct ureg_src376ureg_DECL_image(struct ureg_program *ureg,377unsigned index,378enum tgsi_texture_type target,379enum pipe_format format,380boolean wr,381boolean raw);382383struct ureg_src384ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic);385386struct ureg_src387ureg_DECL_memory(struct ureg_program *ureg, unsigned memory_type);388389static inline struct ureg_src390ureg_imm4f( struct ureg_program *ureg,391float a, float b,392float c, float d)393{394float v[4];395v[0] = a;396v[1] = b;397v[2] = c;398v[3] = d;399return ureg_DECL_immediate( ureg, v, 4 );400}401402static inline struct ureg_src403ureg_imm3f( struct ureg_program *ureg,404float a, float b,405float c)406{407float v[3];408v[0] = a;409v[1] = b;410v[2] = c;411return ureg_DECL_immediate( ureg, v, 3 );412}413414static inline struct ureg_src415ureg_imm2f( struct ureg_program *ureg,416float a, float b)417{418float v[2];419v[0] = a;420v[1] = b;421return ureg_DECL_immediate( ureg, v, 2 );422}423424static inline struct ureg_src425ureg_imm1f( struct ureg_program *ureg,426float a)427{428float v[1];429v[0] = a;430return ureg_DECL_immediate( ureg, v, 1 );431}432433static inline struct ureg_src434ureg_imm4u( struct ureg_program *ureg,435unsigned a, unsigned b,436unsigned c, unsigned d)437{438unsigned v[4];439v[0] = a;440v[1] = b;441v[2] = c;442v[3] = d;443return ureg_DECL_immediate_uint( ureg, v, 4 );444}445446static inline struct ureg_src447ureg_imm3u( struct ureg_program *ureg,448unsigned a, unsigned b,449unsigned c)450{451unsigned v[3];452v[0] = a;453v[1] = b;454v[2] = c;455return ureg_DECL_immediate_uint( ureg, v, 3 );456}457458static inline struct ureg_src459ureg_imm2u( struct ureg_program *ureg,460unsigned a, unsigned b)461{462unsigned v[2];463v[0] = a;464v[1] = b;465return ureg_DECL_immediate_uint( ureg, v, 2 );466}467468static inline struct ureg_src469ureg_imm1u( struct ureg_program *ureg,470unsigned a)471{472return ureg_DECL_immediate_uint( ureg, &a, 1 );473}474475static inline struct ureg_src476ureg_imm4i( struct ureg_program *ureg,477int a, int b,478int c, int d)479{480int v[4];481v[0] = a;482v[1] = b;483v[2] = c;484v[3] = d;485return ureg_DECL_immediate_int( ureg, v, 4 );486}487488static inline struct ureg_src489ureg_imm3i( struct ureg_program *ureg,490int a, int b,491int c)492{493int v[3];494v[0] = a;495v[1] = b;496v[2] = c;497return ureg_DECL_immediate_int( ureg, v, 3 );498}499500static inline struct ureg_src501ureg_imm2i( struct ureg_program *ureg,502int a, int b)503{504int v[2];505v[0] = a;506v[1] = b;507return ureg_DECL_immediate_int( ureg, v, 2 );508}509510static inline struct ureg_src511ureg_imm1i( struct ureg_program *ureg,512int a)513{514return ureg_DECL_immediate_int( ureg, &a, 1 );515}516517/* Where the destination register has a valid file, but an empty518* writemask.519*/520static inline boolean521ureg_dst_is_empty( struct ureg_dst dst )522{523return dst.File != TGSI_FILE_NULL &&524dst.WriteMask == 0;525}526527/***********************************************************************528* Functions for patching up labels529*/530531532/* Will return a number which can be used in a label to point to the533* next instruction to be emitted.534*/535unsigned536ureg_get_instruction_number( struct ureg_program *ureg );537538539/* Patch a given label (expressed as a token number) to point to a540* given instruction (expressed as an instruction number).541*542* Labels are obtained from instruction emitters, eg ureg_CAL().543* Instruction numbers are obtained from ureg_get_instruction_number(),544* above.545*/546void547ureg_fixup_label(struct ureg_program *ureg,548unsigned label_token,549unsigned instruction_number );550551552/* Generic instruction emitter. Use if you need to pass the opcode as553* a parameter, rather than using the emit_OP() variants below.554*/555void556ureg_insn(struct ureg_program *ureg,557enum tgsi_opcode opcode,558const struct ureg_dst *dst,559unsigned nr_dst,560const struct ureg_src *src,561unsigned nr_src,562unsigned precise );563564565void566ureg_tex_insn(struct ureg_program *ureg,567enum tgsi_opcode opcode,568const struct ureg_dst *dst,569unsigned nr_dst,570enum tgsi_texture_type target,571enum tgsi_return_type return_type,572const struct tgsi_texture_offset *texoffsets,573unsigned nr_offset,574const struct ureg_src *src,575unsigned nr_src );576577578void579ureg_memory_insn(struct ureg_program *ureg,580enum tgsi_opcode opcode,581const struct ureg_dst *dst,582unsigned nr_dst,583const struct ureg_src *src,584unsigned nr_src,585unsigned qualifier,586enum tgsi_texture_type texture,587enum pipe_format format);588589/***********************************************************************590* Internal instruction helpers, don't call these directly:591*/592593struct ureg_emit_insn_result {594unsigned insn_token; /*< Used to fixup insn size. */595unsigned extended_token; /*< Used to set the Extended bit, usually the same as insn_token. */596};597598struct ureg_emit_insn_result599ureg_emit_insn(struct ureg_program *ureg,600enum tgsi_opcode opcode,601boolean saturate,602unsigned precise,603unsigned num_dst,604unsigned num_src);605606void607ureg_emit_label(struct ureg_program *ureg,608unsigned insn_token,609unsigned *label_token );610611void612ureg_emit_texture(struct ureg_program *ureg,613unsigned insn_token,614enum tgsi_texture_type target,615enum tgsi_return_type return_type,616unsigned num_offsets);617618void619ureg_emit_texture_offset(struct ureg_program *ureg,620const struct tgsi_texture_offset *offset);621622void623ureg_emit_memory(struct ureg_program *ureg,624unsigned insn_token,625unsigned qualifier,626enum tgsi_texture_type texture,627enum pipe_format format);628629void630ureg_emit_dst( struct ureg_program *ureg,631struct ureg_dst dst );632633void634ureg_emit_src( struct ureg_program *ureg,635struct ureg_src src );636637void638ureg_fixup_insn_size(struct ureg_program *ureg,639unsigned insn );640641642#define OP00( op ) \643static inline void ureg_##op( struct ureg_program *ureg ) \644{ \645enum tgsi_opcode opcode = TGSI_OPCODE_##op; \646struct ureg_emit_insn_result insn; \647insn = ureg_emit_insn(ureg, \648opcode, \649FALSE, \6500, \6510, \6520); \653ureg_fixup_insn_size( ureg, insn.insn_token ); \654}655656#define OP01( op ) \657static inline void ureg_##op( struct ureg_program *ureg, \658struct ureg_src src ) \659{ \660enum tgsi_opcode opcode = TGSI_OPCODE_##op; \661struct ureg_emit_insn_result insn; \662insn = ureg_emit_insn(ureg, \663opcode, \664FALSE, \6650, \6660, \6671); \668ureg_emit_src( ureg, src ); \669ureg_fixup_insn_size( ureg, insn.insn_token ); \670}671672#define OP00_LBL( op ) \673static inline void ureg_##op( struct ureg_program *ureg, \674unsigned *label_token ) \675{ \676enum tgsi_opcode opcode = TGSI_OPCODE_##op; \677struct ureg_emit_insn_result insn; \678insn = ureg_emit_insn(ureg, \679opcode, \680FALSE, \6810, \6820, \6830); \684ureg_emit_label( ureg, insn.extended_token, label_token ); \685ureg_fixup_insn_size( ureg, insn.insn_token ); \686}687688#define OP01_LBL( op ) \689static inline void ureg_##op( struct ureg_program *ureg, \690struct ureg_src src, \691unsigned *label_token ) \692{ \693enum tgsi_opcode opcode = TGSI_OPCODE_##op; \694struct ureg_emit_insn_result insn; \695insn = ureg_emit_insn(ureg, \696opcode, \697FALSE, \6980, \6990, \7001); \701ureg_emit_label( ureg, insn.extended_token, label_token ); \702ureg_emit_src( ureg, src ); \703ureg_fixup_insn_size( ureg, insn.insn_token ); \704}705706#define OP10( op ) \707static inline void ureg_##op( struct ureg_program *ureg, \708struct ureg_dst dst ) \709{ \710enum tgsi_opcode opcode = TGSI_OPCODE_##op; \711struct ureg_emit_insn_result insn; \712if (ureg_dst_is_empty(dst)) \713return; \714insn = ureg_emit_insn(ureg, \715opcode, \716dst.Saturate, \7170, \7181, \7190); \720ureg_emit_dst( ureg, dst ); \721ureg_fixup_insn_size( ureg, insn.insn_token ); \722}723724725#define OP11( op ) \726static inline void ureg_##op( struct ureg_program *ureg, \727struct ureg_dst dst, \728struct ureg_src src ) \729{ \730enum tgsi_opcode opcode = TGSI_OPCODE_##op; \731struct ureg_emit_insn_result insn; \732if (ureg_dst_is_empty(dst)) \733return; \734insn = ureg_emit_insn(ureg, \735opcode, \736dst.Saturate, \7370, \7381, \7391); \740ureg_emit_dst( ureg, dst ); \741ureg_emit_src( ureg, src ); \742ureg_fixup_insn_size( ureg, insn.insn_token ); \743}744745#define OP12( op ) \746static inline void ureg_##op( struct ureg_program *ureg, \747struct ureg_dst dst, \748struct ureg_src src0, \749struct ureg_src src1 ) \750{ \751enum tgsi_opcode opcode = TGSI_OPCODE_##op; \752struct ureg_emit_insn_result insn; \753if (ureg_dst_is_empty(dst)) \754return; \755insn = ureg_emit_insn(ureg, \756opcode, \757dst.Saturate, \7580, \7591, \7602); \761ureg_emit_dst( ureg, dst ); \762ureg_emit_src( ureg, src0 ); \763ureg_emit_src( ureg, src1 ); \764ureg_fixup_insn_size( ureg, insn.insn_token ); \765}766767#define OP12_TEX( op ) \768static inline void ureg_##op( struct ureg_program *ureg, \769struct ureg_dst dst, \770enum tgsi_texture_type target, \771struct ureg_src src0, \772struct ureg_src src1 ) \773{ \774enum tgsi_opcode opcode = TGSI_OPCODE_##op; \775enum tgsi_return_type return_type = TGSI_RETURN_TYPE_UNKNOWN; \776struct ureg_emit_insn_result insn; \777if (ureg_dst_is_empty(dst)) \778return; \779insn = ureg_emit_insn(ureg, \780opcode, \781dst.Saturate, \7820, \7831, \7842); \785ureg_emit_texture( ureg, insn.extended_token, target, \786return_type, 0 ); \787ureg_emit_dst( ureg, dst ); \788ureg_emit_src( ureg, src0 ); \789ureg_emit_src( ureg, src1 ); \790ureg_fixup_insn_size( ureg, insn.insn_token ); \791}792793#define OP13( op ) \794static inline void ureg_##op( struct ureg_program *ureg, \795struct ureg_dst dst, \796struct ureg_src src0, \797struct ureg_src src1, \798struct ureg_src src2 ) \799{ \800enum tgsi_opcode opcode = TGSI_OPCODE_##op; \801struct ureg_emit_insn_result insn; \802if (ureg_dst_is_empty(dst)) \803return; \804insn = ureg_emit_insn(ureg, \805opcode, \806dst.Saturate, \8070, \8081, \8093); \810ureg_emit_dst( ureg, dst ); \811ureg_emit_src( ureg, src0 ); \812ureg_emit_src( ureg, src1 ); \813ureg_emit_src( ureg, src2 ); \814ureg_fixup_insn_size( ureg, insn.insn_token ); \815}816817#define OP14( op ) \818static inline void ureg_##op( struct ureg_program *ureg, \819struct ureg_dst dst, \820struct ureg_src src0, \821struct ureg_src src1, \822struct ureg_src src2, \823struct ureg_src src3 ) \824{ \825enum tgsi_opcode opcode = TGSI_OPCODE_##op; \826struct ureg_emit_insn_result insn; \827if (ureg_dst_is_empty(dst)) \828return; \829insn = ureg_emit_insn(ureg, \830opcode, \831dst.Saturate, \8320, \8331, \8344); \835ureg_emit_dst( ureg, dst ); \836ureg_emit_src( ureg, src0 ); \837ureg_emit_src( ureg, src1 ); \838ureg_emit_src( ureg, src2 ); \839ureg_emit_src( ureg, src3 ); \840ureg_fixup_insn_size( ureg, insn.insn_token ); \841}842843#define OP14_TEX( op ) \844static inline void ureg_##op( struct ureg_program *ureg, \845struct ureg_dst dst, \846enum tgsi_texture_type target, \847struct ureg_src src0, \848struct ureg_src src1, \849struct ureg_src src2, \850struct ureg_src src3 ) \851{ \852enum tgsi_opcode opcode = TGSI_OPCODE_##op; \853enum tgsi_return_type return_type = TGSI_RETURN_TYPE_UNKNOWN; \854struct ureg_emit_insn_result insn; \855if (ureg_dst_is_empty(dst)) \856return; \857insn = ureg_emit_insn(ureg, \858opcode, \859dst.Saturate, \8600, \8611, \8624); \863ureg_emit_texture( ureg, insn.extended_token, target, \864return_type, 0 ); \865ureg_emit_dst( ureg, dst ); \866ureg_emit_src( ureg, src0 ); \867ureg_emit_src( ureg, src1 ); \868ureg_emit_src( ureg, src2 ); \869ureg_emit_src( ureg, src3 ); \870ureg_fixup_insn_size( ureg, insn.insn_token ); \871}872873/* Use a template include to generate a correctly-typed ureg_OP()874* function for each TGSI opcode:875*/876#include "tgsi_opcode_tmp.h"877878879/***********************************************************************880* Inline helpers for manipulating register structs:881*/882static inline struct ureg_src883ureg_negate( struct ureg_src reg )884{885assert(reg.File != TGSI_FILE_NULL);886reg.Negate ^= 1;887return reg;888}889890static inline struct ureg_src891ureg_abs( struct ureg_src reg )892{893assert(reg.File != TGSI_FILE_NULL);894reg.Absolute = 1;895reg.Negate = 0;896return reg;897}898899static inline struct ureg_src900ureg_swizzle( struct ureg_src reg,901int x, int y, int z, int w )902{903unsigned swz = ( (reg.SwizzleX << 0) |904(reg.SwizzleY << 2) |905(reg.SwizzleZ << 4) |906(reg.SwizzleW << 6));907908assert(reg.File != TGSI_FILE_NULL);909assert(x < 4);910assert(y < 4);911assert(z < 4);912assert(w < 4);913914reg.SwizzleX = (swz >> (x*2)) & 0x3;915reg.SwizzleY = (swz >> (y*2)) & 0x3;916reg.SwizzleZ = (swz >> (z*2)) & 0x3;917reg.SwizzleW = (swz >> (w*2)) & 0x3;918return reg;919}920921static inline struct ureg_src922ureg_scalar( struct ureg_src reg, int x )923{924return ureg_swizzle(reg, x, x, x, x);925}926927static inline struct ureg_dst928ureg_writemask( struct ureg_dst reg,929unsigned writemask )930{931assert(reg.File != TGSI_FILE_NULL);932reg.WriteMask &= writemask;933return reg;934}935936static inline struct ureg_dst937ureg_saturate( struct ureg_dst reg )938{939assert(reg.File != TGSI_FILE_NULL);940reg.Saturate = 1;941return reg;942}943944static inline struct ureg_dst945ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )946{947assert(reg.File != TGSI_FILE_NULL);948reg.Indirect = 1;949reg.IndirectFile = addr.File;950reg.IndirectIndex = addr.Index;951reg.IndirectSwizzle = addr.SwizzleX;952return reg;953}954955static inline struct ureg_src956ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )957{958assert(reg.File != TGSI_FILE_NULL);959reg.Indirect = 1;960reg.IndirectFile = addr.File;961reg.IndirectIndex = addr.Index;962reg.IndirectSwizzle = addr.SwizzleX;963return reg;964}965966static inline struct ureg_dst967ureg_dst_dimension( struct ureg_dst reg, int index )968{969assert(reg.File != TGSI_FILE_NULL);970reg.Dimension = 1;971reg.DimIndirect = 0;972reg.DimensionIndex = index;973return reg;974}975976static inline struct ureg_src977ureg_src_dimension( struct ureg_src reg, int index )978{979assert(reg.File != TGSI_FILE_NULL);980reg.Dimension = 1;981reg.DimIndirect = 0;982reg.DimensionIndex = index;983return reg;984}985986static inline struct ureg_dst987ureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr,988int index )989{990assert(reg.File != TGSI_FILE_NULL);991reg.Dimension = 1;992reg.DimIndirect = 1;993reg.DimensionIndex = index;994reg.DimIndFile = addr.File;995reg.DimIndIndex = addr.Index;996reg.DimIndSwizzle = addr.SwizzleX;997return reg;998}9991000static inline struct ureg_src1001ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,1002int index )1003{1004assert(reg.File != TGSI_FILE_NULL);1005reg.Dimension = 1;1006reg.DimIndirect = 1;1007reg.DimensionIndex = index;1008reg.DimIndFile = addr.File;1009reg.DimIndIndex = addr.Index;1010reg.DimIndSwizzle = addr.SwizzleX;1011return reg;1012}10131014static inline struct ureg_src1015ureg_src_array_offset(struct ureg_src reg, int offset)1016{1017reg.Index += offset;1018return reg;1019}10201021static inline struct ureg_dst1022ureg_dst_array_offset( struct ureg_dst reg, int offset )1023{1024reg.Index += offset;1025return reg;1026}10271028static inline struct ureg_dst1029ureg_dst_array_register(unsigned file,1030unsigned index,1031unsigned array_id)1032{1033struct ureg_dst dst;10341035dst.File = file;1036dst.WriteMask = TGSI_WRITEMASK_XYZW;1037dst.Indirect = 0;1038dst.IndirectFile = TGSI_FILE_NULL;1039dst.IndirectIndex = 0;1040dst.IndirectSwizzle = 0;1041dst.Saturate = 0;1042dst.Index = index;1043dst.Dimension = 0;1044dst.DimensionIndex = 0;1045dst.DimIndirect = 0;1046dst.DimIndFile = TGSI_FILE_NULL;1047dst.DimIndIndex = 0;1048dst.DimIndSwizzle = 0;1049dst.ArrayID = array_id;1050dst.Invariant = 0;10511052return dst;1053}10541055static inline struct ureg_dst1056ureg_dst_register(unsigned file,1057unsigned index)1058{1059return ureg_dst_array_register(file, index, 0);1060}10611062static inline struct ureg_dst1063ureg_dst( struct ureg_src src )1064{1065struct ureg_dst dst;10661067dst.File = src.File;1068dst.WriteMask = TGSI_WRITEMASK_XYZW;1069dst.IndirectFile = src.IndirectFile;1070dst.Indirect = src.Indirect;1071dst.IndirectIndex = src.IndirectIndex;1072dst.IndirectSwizzle = src.IndirectSwizzle;1073dst.Saturate = 0;1074dst.Index = src.Index;1075dst.Dimension = src.Dimension;1076dst.DimensionIndex = src.DimensionIndex;1077dst.DimIndirect = src.DimIndirect;1078dst.DimIndFile = src.DimIndFile;1079dst.DimIndIndex = src.DimIndIndex;1080dst.DimIndSwizzle = src.DimIndSwizzle;1081dst.ArrayID = src.ArrayID;1082dst.Invariant = 0;10831084return dst;1085}10861087static inline struct ureg_src1088ureg_src_array_register(unsigned file,1089unsigned index,1090unsigned array_id)1091{1092struct ureg_src src;10931094src.File = file;1095src.SwizzleX = TGSI_SWIZZLE_X;1096src.SwizzleY = TGSI_SWIZZLE_Y;1097src.SwizzleZ = TGSI_SWIZZLE_Z;1098src.SwizzleW = TGSI_SWIZZLE_W;1099src.Indirect = 0;1100src.IndirectFile = TGSI_FILE_NULL;1101src.IndirectIndex = 0;1102src.IndirectSwizzle = 0;1103src.Absolute = 0;1104src.Index = index;1105src.Negate = 0;1106src.Dimension = 0;1107src.DimensionIndex = 0;1108src.DimIndirect = 0;1109src.DimIndFile = TGSI_FILE_NULL;1110src.DimIndIndex = 0;1111src.DimIndSwizzle = 0;1112src.ArrayID = array_id;11131114return src;1115}11161117static inline struct ureg_src1118ureg_src_register(unsigned file,1119unsigned index)1120{1121return ureg_src_array_register(file, index, 0);1122}11231124static inline struct ureg_src1125ureg_src( struct ureg_dst dst )1126{1127struct ureg_src src;11281129src.File = dst.File;1130src.SwizzleX = TGSI_SWIZZLE_X;1131src.SwizzleY = TGSI_SWIZZLE_Y;1132src.SwizzleZ = TGSI_SWIZZLE_Z;1133src.SwizzleW = TGSI_SWIZZLE_W;1134src.Indirect = dst.Indirect;1135src.IndirectFile = dst.IndirectFile;1136src.IndirectIndex = dst.IndirectIndex;1137src.IndirectSwizzle = dst.IndirectSwizzle;1138src.Absolute = 0;1139src.Index = dst.Index;1140src.Negate = 0;1141src.Dimension = dst.Dimension;1142src.DimensionIndex = dst.DimensionIndex;1143src.DimIndirect = dst.DimIndirect;1144src.DimIndFile = dst.DimIndFile;1145src.DimIndIndex = dst.DimIndIndex;1146src.DimIndSwizzle = dst.DimIndSwizzle;1147src.ArrayID = dst.ArrayID;11481149return src;1150}1151115211531154static inline struct ureg_dst1155ureg_dst_undef( void )1156{1157struct ureg_dst dst;11581159dst.File = TGSI_FILE_NULL;1160dst.WriteMask = 0;1161dst.Indirect = 0;1162dst.IndirectFile = TGSI_FILE_NULL;1163dst.IndirectIndex = 0;1164dst.IndirectSwizzle = 0;1165dst.Saturate = 0;1166dst.Index = 0;1167dst.Dimension = 0;1168dst.DimensionIndex = 0;1169dst.DimIndirect = 0;1170dst.DimIndFile = TGSI_FILE_NULL;1171dst.DimIndIndex = 0;1172dst.DimIndSwizzle = 0;1173dst.ArrayID = 0;1174dst.Invariant = 0;11751176return dst;1177}11781179static inline struct ureg_src1180ureg_src_undef( void )1181{1182struct ureg_src src;11831184src.File = TGSI_FILE_NULL;1185src.SwizzleX = 0;1186src.SwizzleY = 0;1187src.SwizzleZ = 0;1188src.SwizzleW = 0;1189src.Indirect = 0;1190src.IndirectFile = TGSI_FILE_NULL;1191src.IndirectIndex = 0;1192src.IndirectSwizzle = 0;1193src.Absolute = 0;1194src.Index = 0;1195src.Negate = 0;1196src.Dimension = 0;1197src.DimensionIndex = 0;1198src.DimIndirect = 0;1199src.DimIndFile = TGSI_FILE_NULL;1200src.DimIndIndex = 0;1201src.DimIndSwizzle = 0;1202src.ArrayID = 0;12031204return src;1205}12061207static inline boolean1208ureg_src_is_undef( struct ureg_src src )1209{1210return src.File == TGSI_FILE_NULL;1211}12121213static inline boolean1214ureg_dst_is_undef( struct ureg_dst dst )1215{1216return dst.File == TGSI_FILE_NULL;1217}12181219void1220ureg_setup_shader_info(struct ureg_program *ureg,1221const struct shader_info *info);12221223#ifdef __cplusplus1224}1225#endif12261227#endif122812291230