diff options
Diffstat (limited to 'src/mesa')
22 files changed, 7229 insertions, 7 deletions
diff --git a/src/mesa/pipe/tgsi/Makefile b/src/mesa/pipe/tgsi/Makefile new file mode 100644 index 0000000000..12a8bd0409 --- /dev/null +++ b/src/mesa/pipe/tgsi/Makefile @@ -0,0 +1,3 @@ +default: + cd ../.. ; make + diff --git a/src/mesa/pipe/tgsi/core/Makefile b/src/mesa/pipe/tgsi/core/Makefile new file mode 100644 index 0000000000..eb8b14e0e8 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/Makefile @@ -0,0 +1,3 @@ +default: + cd ../../.. ; make + diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.c b/src/mesa/pipe/tgsi/core/tgsi_build.c new file mode 100644 index 0000000000..2a482a78dc --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_build.c @@ -0,0 +1,1315 @@ +#include "tgsi_platform.h" +#include "tgsi_core.h" + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ) +{ + struct tgsi_version version; + + version.MajorVersion = 1; + version.MinorVersion = 1; + version.Padding = 0; + + return version; +} + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ) +{ + struct tgsi_header header; + + header.HeaderSize = 1; + header.BodySize = 0; + + return header; +} + +static void +header_headersize_grow( struct tgsi_header *header ) +{ + assert (header->HeaderSize < 0xFF); + assert (header->BodySize == 0); + + header->HeaderSize++; +} + +static void +header_bodysize_grow( struct tgsi_header *header ) +{ + assert (header->BodySize < 0xFFFFFF); + + header->BodySize++; +} + +struct tgsi_processor +tgsi_default_processor( void ) +{ + struct tgsi_processor processor; + + processor.Processor = TGSI_PROCESSOR_FRAGMENT; + processor.Padding = 0; + + return processor; +} + +struct tgsi_processor +tgsi_build_processor( + GLuint type, + struct tgsi_header *header ) +{ + struct tgsi_processor processor; + + processor = tgsi_default_processor(); + processor.Processor = type; + + header_headersize_grow( header ); + + return processor; +} + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ) +{ + struct tgsi_declaration declaration; + + declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; + declaration.Size = 1; + declaration.File = TGSI_FILE_NULL; + declaration.Declare = TGSI_DECLARE_RANGE; + declaration.Interpolate = 0; + declaration.Padding = 0; + declaration.Extended = 0; + + return declaration; +} + +struct tgsi_declaration +tgsi_build_declaration( + GLuint file, + GLuint declare, + GLuint interpolate, + struct tgsi_header *header ) +{ + struct tgsi_declaration declaration; + + assert (file <= TGSI_FILE_IMMEDIATE); + assert (declare <= TGSI_DECLARE_MASK); + + declaration = tgsi_default_declaration(); + declaration.File = file; + declaration.Declare = declare; + declaration.Interpolate = interpolate; + + header_bodysize_grow( header ); + + return declaration; +} + +static void +declaration_grow( + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + assert (declaration->Size < 0xFF); + + declaration->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ) +{ + struct tgsi_full_declaration full_declaration; + + full_declaration.Declaration = tgsi_default_declaration(); + full_declaration.Interpolation = tgsi_default_declaration_interpolation(); + + return full_declaration; +} + +GLuint +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ) +{ + GLuint size = 0; + struct tgsi_declaration *declaration; + + if( maxsize <= size ) + return 0; + declaration = (struct tgsi_declaration *) &tokens[size]; + size++; + + *declaration = tgsi_build_declaration( + full_decl->Declaration.File, + full_decl->Declaration.Declare, + full_decl->Declaration.Interpolate, + header ); + + switch( full_decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + { + struct tgsi_declaration_range *dr; + + if( maxsize <= size ) + return 0; + dr = (struct tgsi_declaration_range *) &tokens[size]; + size++; + + *dr = tgsi_build_declaration_range( + full_decl->u.DeclarationRange.First, + full_decl->u.DeclarationRange.Last, + declaration, + header ); + break; + } + + case TGSI_DECLARE_MASK: + { + struct tgsi_declaration_mask *dm; + + if( maxsize <= size ) + return 0; + dm = (struct tgsi_declaration_mask *) &tokens[size]; + size++; + + *dm = tgsi_build_declaration_mask( + full_decl->u.DeclarationMask.Mask, + declaration, + header ); + break; + } + + default: + assert( 0 ); + } + + if( full_decl->Declaration.Interpolate ) { + struct tgsi_declaration_interpolation *di; + + if( maxsize <= size ) + return 0; + di = (struct tgsi_declaration_interpolation *) &tokens[size]; + size++; + + *di = tgsi_build_declaration_interpolation( + full_decl->Interpolation.Interpolate, + declaration, + header ); + } + + return size; +} + +struct tgsi_declaration_range +tgsi_build_declaration_range( + GLuint first, + GLuint last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_range declaration_range; + + assert (last >= first); + assert (last <= 0xFFFF); + + declaration_range.First = first; + declaration_range.Last = last; + + declaration_grow( declaration, header ); + + return declaration_range; +} + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + GLuint mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_mask declaration_mask; + + declaration_mask.Mask = mask; + + declaration_grow( declaration, header ); + + return declaration_mask; +} + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ) +{ + struct tgsi_declaration_interpolation di; + + di.Interpolate = TGSI_INTERPOLATE_CONSTANT; + di.Padding = 0; + + return di; +} + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + GLuint interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_interpolation di; + + assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); + + di = tgsi_default_declaration_interpolation(); + di.Interpolate = interpolate; + + declaration_grow( declaration, header ); + + return di; +} + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ) +{ + struct tgsi_immediate immediate; + + immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; + immediate.Size = 1; + immediate.DataType = TGSI_IMM_FLOAT32; + immediate.Padding = 0; + immediate.Extended = 0; + + return immediate; +} + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ) +{ + struct tgsi_immediate immediate; + + immediate = tgsi_default_immediate(); + + header_bodysize_grow( header ); + + return immediate; +} + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ) +{ + struct tgsi_full_immediate fullimm; + + fullimm.Immediate = tgsi_default_immediate(); + fullimm.u.Pointer = (void *) 0; + + return fullimm; +} + +static void +immediate_grow( + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + assert( immediate->Size < 0xFF ); + + immediate->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + GLfloat value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + struct tgsi_immediate_float32 immediate_float32; + + immediate_float32.Float = value; + + immediate_grow( immediate, header ); + + return immediate_float32; +} + +GLuint +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ) +{ + GLuint size = 0, i; + struct tgsi_immediate *immediate; + + if( maxsize <= size ) + return 0; + immediate = (struct tgsi_immediate *) &tokens[size]; + size++; + + *immediate = tgsi_build_immediate( header ); + + for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { + struct tgsi_immediate_float32 *if32; + + if( maxsize <= size ) + return 0; + if32 = (struct tgsi_immediate_float32 *) &tokens[size]; + size++; + + *if32 = tgsi_build_immediate_float32( + full_imm->u.ImmediateFloat32[i].Float, + immediate, + header ); + } + + return size; +} + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ) +{ + struct tgsi_instruction instruction; + + instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; + instruction.Size = 1; + instruction.Opcode = TGSI_OPCODE_MOV; + instruction.Saturate = TGSI_SAT_NONE; + instruction.NumDstRegs = 1; + instruction.NumSrcRegs = 1; + instruction.Padding = 0; + instruction.Extended = 0; + + return instruction; +} + +struct tgsi_instruction +tgsi_build_instruction( + GLuint opcode, + GLuint saturate, + GLuint num_dst_regs, + GLuint num_src_regs, + struct tgsi_header *header ) +{ + struct tgsi_instruction instruction; + + assert (opcode <= TGSI_OPCODE_LAST); + assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); + assert (num_dst_regs <= 3); + assert (num_src_regs <= 15); + + instruction = tgsi_default_instruction(); + instruction.Opcode = opcode; + instruction.Saturate = saturate; + instruction.NumDstRegs = num_dst_regs; + instruction.NumSrcRegs = num_src_regs; + + header_bodysize_grow( header ); + + return instruction; +} + +static void +instruction_grow( + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + assert (instruction->Size < 0xFF); + + instruction->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ) +{ + struct tgsi_full_instruction full_instruction; + GLuint i; + + full_instruction.Instruction = tgsi_default_instruction(); + full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); + full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); + full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); + for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { + full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); + } + for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { + full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); + } + + return full_instruction; +} + +GLuint +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ) +{ + GLuint size = 0; + GLuint i; + struct tgsi_instruction *instruction; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + instruction = (struct tgsi_instruction *) &tokens[size]; + size++; + + *instruction = tgsi_build_instruction( + full_inst->Instruction.Opcode, + full_inst->Instruction.Saturate, + full_inst->Instruction.NumDstRegs, + full_inst->Instruction.NumSrcRegs, + header ); + prev_token = (struct tgsi_token *) instruction; + + if( tgsi_compare_instruction_ext_nv( + full_inst->InstructionExtNv, + tgsi_default_instruction_ext_nv() ) ) { + struct tgsi_instruction_ext_nv *instruction_ext_nv; + + if( maxsize <= size ) + return 0; + instruction_ext_nv = + (struct tgsi_instruction_ext_nv *) &tokens[size]; + size++; + + *instruction_ext_nv = tgsi_build_instruction_ext_nv( + full_inst->InstructionExtNv.Precision, + full_inst->InstructionExtNv.CondDstIndex, + full_inst->InstructionExtNv.CondFlowIndex, + full_inst->InstructionExtNv.CondMask, + full_inst->InstructionExtNv.CondSwizzleX, + full_inst->InstructionExtNv.CondSwizzleY, + full_inst->InstructionExtNv.CondSwizzleZ, + full_inst->InstructionExtNv.CondSwizzleW, + full_inst->InstructionExtNv.CondDstUpdate, + full_inst->InstructionExtNv.CondFlowEnable, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_nv; + } + + if( tgsi_compare_instruction_ext_label( + full_inst->InstructionExtLabel, + tgsi_default_instruction_ext_label() ) ) { + struct tgsi_instruction_ext_label *instruction_ext_label; + + if( maxsize <= size ) + return 0; + instruction_ext_label = + (struct tgsi_instruction_ext_label *) &tokens[size]; + size++; + + *instruction_ext_label = tgsi_build_instruction_ext_label( + full_inst->InstructionExtLabel.Label, + full_inst->InstructionExtLabel.Target, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_label; + } + + if( tgsi_compare_instruction_ext_texture( + full_inst->InstructionExtTexture, + tgsi_default_instruction_ext_texture() ) ) { + struct tgsi_instruction_ext_texture *instruction_ext_texture; + + if( maxsize <= size ) + return 0; + instruction_ext_texture = + (struct tgsi_instruction_ext_texture *) &tokens[size]; + size++; + + *instruction_ext_texture = tgsi_build_instruction_ext_texture( + full_inst->InstructionExtTexture.Texture, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_texture; + } + + for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { + const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; + struct tgsi_dst_register *dst_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + dst_register = (struct tgsi_dst_register *) &tokens[size]; + size++; + + *dst_register = tgsi_build_dst_register( + reg->DstRegister.File, + reg->DstRegister.WriteMask, + reg->DstRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register; + + if( tgsi_compare_dst_register_ext_concode( + reg->DstRegisterExtConcode, + tgsi_default_dst_register_ext_concode() ) ) { + struct tgsi_dst_register_ext_concode *dst_register_ext_concode; + + if( maxsize <= size ) + return 0; + dst_register_ext_concode = + (struct tgsi_dst_register_ext_concode *) &tokens[size]; + size++; + + *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( + reg->DstRegisterExtConcode.CondMask, + reg->DstRegisterExtConcode.CondSwizzleX, + reg->DstRegisterExtConcode.CondSwizzleY, + reg->DstRegisterExtConcode.CondSwizzleZ, + reg->DstRegisterExtConcode.CondSwizzleW, + reg->DstRegisterExtConcode.CondSrcIndex, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_concode; + } + + if( tgsi_compare_dst_register_ext_modulate( + reg->DstRegisterExtModulate, + tgsi_default_dst_register_ext_modulate() ) ) { + struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; + + if( maxsize <= size ) + return 0; + dst_register_ext_modulate = + (struct tgsi_dst_register_ext_modulate *) &tokens[size]; + size++; + + *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( + reg->DstRegisterExtModulate.Modulate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_modulate; + } + } + + for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { + const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; + struct tgsi_src_register *src_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + src_register = (struct tgsi_src_register *) &tokens[size]; + size++; + + *src_register = tgsi_build_src_register( + reg->SrcRegister.File, + reg->SrcRegister.SwizzleX, + reg->SrcRegister.SwizzleY, + reg->SrcRegister.SwizzleZ, + reg->SrcRegister.SwizzleW, + reg->SrcRegister.Negate, + reg->SrcRegister.Indirect, + reg->SrcRegister.Dimension, + reg->SrcRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register; + + if( tgsi_compare_src_register_ext_swz( + reg->SrcRegisterExtSwz, + tgsi_default_src_register_ext_swz() ) ) { + struct tgsi_src_register_ext_swz *src_register_ext_swz; + + if( maxsize <= size ) + return 0; + src_register_ext_swz = + (struct tgsi_src_register_ext_swz *) &tokens[size]; + size++; + + *src_register_ext_swz = tgsi_build_src_register_ext_swz( + reg->SrcRegisterExtSwz.ExtSwizzleX, + reg->SrcRegisterExtSwz.ExtSwizzleY, + reg->SrcRegisterExtSwz.ExtSwizzleZ, + reg->SrcRegisterExtSwz.ExtSwizzleW, + reg->SrcRegisterExtSwz.NegateX, + reg->SrcRegisterExtSwz.NegateY, + reg->SrcRegisterExtSwz.NegateZ, + reg->SrcRegisterExtSwz.NegateW, + reg->SrcRegisterExtSwz.ExtDivide, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_swz; + } + + if( tgsi_compare_src_register_ext_mod( + reg->SrcRegisterExtMod, + tgsi_default_src_register_ext_mod() ) ) { + struct tgsi_src_register_ext_mod *src_register_ext_mod; + + if( maxsize <= size ) + return 0; + src_register_ext_mod = + (struct tgsi_src_register_ext_mod *) &tokens[size]; + size++; + + *src_register_ext_mod = tgsi_build_src_register_ext_mod( + reg->SrcRegisterExtMod.Complement, + reg->SrcRegisterExtMod.Bias, + reg->SrcRegisterExtMod.Scale2X, + reg->SrcRegisterExtMod.Absolute, + reg->SrcRegisterExtMod.Negate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_mod; + } + + if( reg->SrcRegister.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterInd.File, + reg->SrcRegisterInd.SwizzleX, + reg->SrcRegisterInd.SwizzleY, + reg->SrcRegisterInd.SwizzleZ, + reg->SrcRegisterInd.SwizzleW, + reg->SrcRegisterInd.Negate, + reg->SrcRegisterInd.Indirect, + reg->SrcRegisterInd.Dimension, + reg->SrcRegisterInd.Index, + instruction, + header ); + } + + if( reg->SrcRegister.Dimension ) { + struct tgsi_dimension *dim; + + assert( !reg->SrcRegisterDim.Dimension ); + + if( maxsize <= size ) + return 0; + dim = (struct tgsi_dimension *) &tokens[size]; + size++; + + *dim = tgsi_build_dimension( + reg->SrcRegisterDim.Indirect, + reg->SrcRegisterDim.Index, + instruction, + header ); + + if( reg->SrcRegisterDim.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterDimInd.File, + reg->SrcRegisterDimInd.SwizzleX, + reg->SrcRegisterDimInd.SwizzleY, + reg->SrcRegisterDimInd.SwizzleZ, + reg->SrcRegisterDimInd.SwizzleW, + reg->SrcRegisterDimInd.Negate, + reg->SrcRegisterDimInd.Indirect, + reg->SrcRegisterDimInd.Dimension, + reg->SrcRegisterDimInd.Index, + instruction, + header ); + } + } + } + + return size; +} + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; + instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; + instruction_ext_nv.CondDstIndex = 0; + instruction_ext_nv.CondFlowIndex = 0; + instruction_ext_nv.CondMask = TGSI_CC_TR; + instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; + instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; + instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; + instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; + instruction_ext_nv.CondDstUpdate = 0; + instruction_ext_nv.CondFlowEnable = 0; + instruction_ext_nv.Padding = 0; + instruction_ext_nv.Extended = 0; + + return instruction_ext_nv; +} + +union token_u32 +{ + GLuint u32; +}; + +GLuint +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + GLuint precision, + GLuint cond_dst_index, + GLuint cond_flow_index, + GLuint cond_mask, + GLuint cond_swizzle_x, + GLuint cond_swizzle_y, + GLuint cond_swizzle_z, + GLuint cond_swizzle_w, + GLuint cond_dst_update, + GLuint cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv = tgsi_default_instruction_ext_nv(); + instruction_ext_nv.Precision = precision; + instruction_ext_nv.CondDstIndex = cond_dst_index; + instruction_ext_nv.CondFlowIndex = cond_flow_index; + instruction_ext_nv.CondMask = cond_mask; + instruction_ext_nv.CondSwizzleX = cond_swizzle_x; + instruction_ext_nv.CondSwizzleY = cond_swizzle_y; + instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; + instruction_ext_nv.CondSwizzleW = cond_swizzle_w; + instruction_ext_nv.CondDstUpdate = cond_dst_update; + instruction_ext_nv.CondFlowEnable = cond_flow_update; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_nv; +} + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; + instruction_ext_label.Label = 0; + instruction_ext_label.Target = 0; + instruction_ext_label.Padding = 0; + instruction_ext_label.Extended = 0; + + return instruction_ext_label; +} + +GLuint +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + GLuint label, + GLuint target, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label = tgsi_default_instruction_ext_label(); + instruction_ext_label.Label = label; + instruction_ext_label.Target = target; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_label; +} + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; + instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_ext_texture.Padding = 0; + instruction_ext_texture.Extended = 0; + + return instruction_ext_texture; +} + +GLuint +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + GLuint texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture = tgsi_default_instruction_ext_texture(); + instruction_ext_texture.Texture = texture; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_texture; +} + +struct tgsi_src_register +tgsi_default_src_register( void ) +{ + struct tgsi_src_register src_register; + + src_register.File = TGSI_FILE_NULL; + src_register.SwizzleX = TGSI_SWIZZLE_X; + src_register.SwizzleY = TGSI_SWIZZLE_Y; + src_register.SwizzleZ = TGSI_SWIZZLE_Z; + src_register.SwizzleW = TGSI_SWIZZLE_W; + src_register.Negate = 0; + src_register.Indirect = 0; + src_register.Dimension = 0; + src_register.Index = 0; + src_register.Extended = 0; + + return src_register; +} + +struct tgsi_src_register +tgsi_build_src_register( + GLuint file, + GLuint swizzle_x, + GLuint swizzle_y, + GLuint swizzle_z, + GLuint swizzle_w, + GLuint negate, + GLuint indirect, + GLuint dimension, + GLint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register src_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( negate <= 1 ); + assert( index >= -0x8000 && index <= 0x7FFF ); + + src_register = tgsi_default_src_register(); + src_register.File = file; + src_register.SwizzleX = swizzle_x; + src_register.SwizzleY = swizzle_y; + src_register.SwizzleZ = swizzle_z; + src_register.SwizzleW = swizzle_w; + src_register.Negate = negate; + src_register.Indirect = indirect; + src_register.Dimension = dimension; + src_register.Index = index; + + instruction_grow( instruction, header ); + + return src_register; +} + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ) +{ + struct tgsi_full_src_register full_src_register; + + full_src_register.SrcRegister = tgsi_default_src_register(); + full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); + full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); + full_src_register.SrcRegisterInd = tgsi_default_src_register(); + full_src_register.SrcRegisterDim = tgsi_default_dimension(); + full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); + + return full_src_register; +} + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; + src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; + src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; + src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; + src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; + src_register_ext_swz.NegateX = 0; + src_register_ext_swz.NegateY = 0; + src_register_ext_swz.NegateZ = 0; + src_register_ext_swz.NegateW = 0; + src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE; + src_register_ext_swz.Padding = 0; + src_register_ext_swz.Extended = 0; + + return src_register_ext_swz; +} + +GLuint +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + GLuint ext_swizzle_x, + GLuint ext_swizzle_y, + GLuint ext_swizzle_z, + GLuint ext_swizzle_w, + GLuint negate_x, + GLuint negate_y, + GLuint negate_z, + GLuint negate_w, + GLuint ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + assert (ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE); + assert (ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE); + assert (ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE); + assert (ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE); + assert (negate_x <= 1); + assert (negate_y <= 1); + assert (negate_z <= 1); + assert (negate_w <= 1); + assert (ext_divide <= TGSI_EXTSWIZZLE_ONE); + + src_register_ext_swz = tgsi_default_src_register_ext_swz(); + src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; + src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; + src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; + src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; + src_register_ext_swz.NegateX = negate_x; + src_register_ext_swz.NegateY = negate_y; + src_register_ext_swz.NegateZ = negate_z; + src_register_ext_swz.NegateW = negate_w; + src_register_ext_swz.ExtDivide = ext_divide; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_swz; +} + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; + src_register_ext_mod.Complement = 0; + src_register_ext_mod.Bias = 0; + src_register_ext_mod.Scale2X = 0; + src_register_ext_mod.Absolute = 0; + src_register_ext_mod.Negate = 0; + src_register_ext_mod.Padding = 0; + src_register_ext_mod.Extended = 0; + + return src_register_ext_mod; +} + +GLuint +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + GLuint complement, + GLuint bias, + GLuint scale_2x, + GLuint absolute, + GLuint negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + assert (complement <= 1); + assert (bias <= 1); + assert (scale_2x <= 1); + assert (absolute <= 1); + assert (negate <= 1); + + src_register_ext_mod = tgsi_default_src_register_ext_mod(); + src_register_ext_mod.Complement = complement; + src_register_ext_mod.Bias = bias; + src_register_ext_mod.Scale2X = scale_2x; + src_register_ext_mod.Absolute = absolute; + src_register_ext_mod.Negate = negate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_mod; +} + +struct tgsi_dimension +tgsi_default_dimension( void ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = 0; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = 0; + dimension.Extended = 0; + + return dimension; +} + +struct tgsi_dimension +tgsi_build_dimension( + GLuint indirect, + GLuint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dimension dimension; + + dimension = tgsi_default_dimension(); + dimension.Indirect = indirect; + dimension.Index = index; + + instruction_grow( instruction, header ); + + return dimension; +} + +struct tgsi_dst_register +tgsi_default_dst_register( void ) +{ + struct tgsi_dst_register dst_register; + + dst_register.File = TGSI_FILE_NULL; + dst_register.WriteMask = TGSI_WRITEMASK_XYZW; + dst_register.Indirect = 0; + dst_register.Dimension = 0; + dst_register.Index = 0; + dst_register.Padding = 0; + dst_register.Extended = 0; + + return dst_register; +} + +struct tgsi_dst_register +tgsi_build_dst_register( + GLuint file, + GLuint mask, + GLint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register dst_register; + + assert (file <= TGSI_FILE_IMMEDIATE); + assert (mask <= TGSI_WRITEMASK_XYZW); + assert (index >= -32768 && index <= 32767); + + dst_register = tgsi_default_dst_register(); + dst_register.File = file; + dst_register.WriteMask = mask; + dst_register.Index = index; + + instruction_grow( instruction, header ); + + return dst_register; +} + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ) +{ + struct tgsi_full_dst_register full_dst_register; + + full_dst_register.DstRegister = tgsi_default_dst_register(); + full_dst_register.DstRegisterExtConcode = + tgsi_default_dst_register_ext_concode(); + full_dst_register.DstRegisterExtModulate = + tgsi_default_dst_register_ext_modulate(); + + return full_dst_register; +} + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; + dst_register_ext_concode.CondMask = TGSI_CC_TR; + dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; + dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; + dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; + dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; + dst_register_ext_concode.CondSrcIndex = 0; + dst_register_ext_concode.Padding = 0; + dst_register_ext_concode.Extended = 0; + + return dst_register_ext_concode; +} + +GLuint +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + GLuint cc, + GLuint swizzle_x, + GLuint swizzle_y, + GLuint swizzle_z, + GLuint swizzle_w, + GLint index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + assert (cc <= TGSI_CC_FL); + assert (swizzle_x <= TGSI_SWIZZLE_W); + assert (swizzle_y <= TGSI_SWIZZLE_W); + assert (swizzle_z <= TGSI_SWIZZLE_W); + assert (swizzle_w <= TGSI_SWIZZLE_W); + assert (index >= -32768 && index <= 32767); + + dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); + dst_register_ext_concode.CondMask = cc; + dst_register_ext_concode.CondSwizzleX = swizzle_x; + dst_register_ext_concode.CondSwizzleY = swizzle_y; + dst_register_ext_concode.CondSwizzleZ = swizzle_z; + dst_register_ext_concode.CondSwizzleW = swizzle_w; + dst_register_ext_concode.CondSrcIndex = index; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_concode; +} + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; + dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; + dst_register_ext_modulate.Padding = 0; + dst_register_ext_modulate.Extended = 0; + + return dst_register_ext_modulate; +} + +GLuint +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return *(GLuint *) &a != *(GLuint *) &b; +} + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + GLuint modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + assert (modulate <= TGSI_MODULATE_EIGHTH); + + dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); + dst_register_ext_modulate.Modulate = modulate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_modulate; +} + diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.h b/src/mesa/pipe/tgsi/core/tgsi_build.h new file mode 100644 index 0000000000..db25956519 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_build.h @@ -0,0 +1,309 @@ +#if !defined TGSI_BUILD_H +#define TGSI_BUILD_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ); + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ); + +struct tgsi_processor +tgsi_default_processor( void ); + +struct tgsi_processor +tgsi_build_processor( + GLuint processor, + struct tgsi_header *header ); + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ); + +struct tgsi_declaration +tgsi_build_declaration( + GLuint file, + GLuint declare, + GLuint interpolate, + struct tgsi_header *header ); + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ); + +GLuint +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ); + +struct tgsi_declaration_range +tgsi_build_declaration_range( + GLuint first, + GLuint last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + GLuint mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ); + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + GLuint interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ); + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ); + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ); + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + GLfloat value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ); + +GLuint +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ); + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ); + +struct tgsi_instruction +tgsi_build_instruction( + GLuint opcode, + GLuint saturate, + GLuint num_dst_regs, + GLuint num_src_regs, + struct tgsi_header *header ); + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ); + +GLuint +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + GLuint maxsize ); + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ); + +GLuint +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ); + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + GLuint precision, + GLuint cond_dst_index, + GLuint cond_flow_index, + GLuint cond_mask, + GLuint cond_swizzle_x, + GLuint cond_swizzle_y, + GLuint cond_swizzle_z, + GLuint cond_swizzle_w, + GLuint cond_dst_update, + GLuint cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ); + +GLuint +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ); + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + GLuint label, + GLuint target, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ); + +GLuint +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ); + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + GLuint texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register +tgsi_default_src_register( void ); + +struct tgsi_src_register +tgsi_build_src_register( + GLuint file, + GLuint swizzle_x, + GLuint swizzle_y, + GLuint swizzle_z, + GLuint swizzle_w, + GLuint negate, + GLuint indirect, + GLuint dimension, + GLint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ); + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ); + +GLuint +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ); + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + GLuint ext_swizzle_x, + GLuint ext_swizzle_y, + GLuint ext_swizzle_z, + GLuint ext_swizzle_w, + GLuint negate_x, + GLuint negate_y, + GLuint negate_z, + GLuint negate_w, + GLuint ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ); + +GLuint +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ); + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + GLuint complement, + GLuint bias, + GLuint scale_2x, + GLuint absolute, + GLuint negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dimension +tgsi_default_dimension( void ); + +struct tgsi_dimension +tgsi_build_dimension( + GLuint indirect, + GLuint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register +tgsi_default_dst_register( void ); + +struct tgsi_dst_register +tgsi_build_dst_register( + GLuint file, + GLuint mask, + GLint index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ); + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ); + +GLuint +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ); + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + GLuint cc, + GLuint swizzle_x, + GLuint swizzle_y, + GLuint swizzle_z, + GLuint swizzle_w, + GLint index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ); + +GLuint +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ); + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + GLuint modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_BUILD_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_core.h b/src/mesa/pipe/tgsi/core/tgsi_core.h new file mode 100644 index 0000000000..1f5f00a38e --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_core.h @@ -0,0 +1,12 @@ +#if !defined TGSI_CORE_H +#define TGSI_CORE_H + +#include "tgsi_token.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" +#include "tgsi_exec.h" +#include "tgsi_dump.h" +#include "tgsi_util.h" + +#endif // !defined TGSI_CORE_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_dump.c b/src/mesa/pipe/tgsi/core/tgsi_dump.c new file mode 100644 index 0000000000..fecb246ab1 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_dump.c @@ -0,0 +1,871 @@ +#include "tgsi_platform.h" +#include "tgsi_core.h" + +struct text_dump +{ + FILE *file; + GLuint tabs; +}; + +static void +text_dump_write( + struct text_dump *dump, + const void *buffer, + GLuint size ) +{ + fwrite( buffer, size, 1, dump->file ); +} + +static void +text_dump_str( + struct text_dump *dump, + const char *str ) +{ + GLuint i; + GLuint len = strlen( str ); + + for( i = 0; i < len; i++ ) { + text_dump_write( dump, &str[i], 1 ); + + if( str[i] == '\n' ) { + GLuint i; + + for( i = 0; i < dump->tabs; i++ ) { + text_dump_write( dump, " ", 4 ); + } + } + } +} + +static void +text_dump_chr( + struct text_dump *dump, + const char chr ) +{ + char str[2]; + + str[0] = chr; + str[1] = '\0'; + text_dump_str( dump, str ); +} + +static void +text_dump_uix( + struct text_dump *dump, + const GLuint ui) +{ + char str[36]; + + sprintf( str, "0x%x", ui ); + text_dump_str( dump, str ); +} + +static void +text_dump_uid( + struct text_dump *dump, + const GLuint ui ) +{ + char str[16]; + + sprintf( str, "%u", ui ); + text_dump_str( dump, str ); +} + +static void +text_dump_sid( + struct text_dump *dump, + const GLint si ) +{ + char str[16]; + + sprintf( str, "%d", si ); + text_dump_str( dump, str ); +} + +static void +text_dump_flt( + struct text_dump *dump, + const GLfloat f ) +{ + char str[48]; + + sprintf( str, "%40.6f", f ); + text_dump_str( dump, str ); +} + +static void +text_dump_enum( + struct text_dump *dump, + const GLuint e, + const char **enums, + const GLuint enums_count ) +{ + if( e >= enums_count ) { + text_dump_uid( dump, e ); + } + else { + text_dump_str( dump, enums[e] ); + } +} + +static void +text_dump_tab( + struct text_dump *dump ) +{ + dump->tabs++; +} + +static void +text_dump_untab( + struct text_dump *dump ) +{ + assert( dump->tabs > 0 ); + + --dump->tabs; +} + +#define TXT(S) text_dump_str( &dump, S ) +#define CHR(C) text_dump_chr( &dump, C ) +#define UIX(I) text_dump_uix( &dump, I ) +#define UID(I) text_dump_uid( &dump, I ) +#define SID(I) text_dump_sid( &dump, I ) +#define FLT(F) text_dump_flt( &dump, F ) +#define TAB() text_dump_tab( &dump ) +#define UNT() text_dump_untab( &dump ) +#define ENM(E,ENUMS) text_dump_enum( &dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *TGSI_PROCESSOR_TYPES[] = +{ + "PROCESSOR_FRAGMENT", + "PROCESSOR_VERTEX" +}; + +static const char *TGSI_TOKEN_TYPES[] = +{ + "TOKEN_TYPE_DECLARATION", + "TOKEN_TYPE_IMMEDIATE", + "TOKEN_TYPE_INSTRUCTION" +}; + +static const char *TGSI_FILES[] = +{ + "FILE_NULL", + "FILE_CONSTANT", + "FILE_INPUT", + "FILE_OUTPUT", + "FILE_TEMPORARY", + "FILE_SAMPLER", + "FILE_ADDRESS", + "FILE_IMMEDIATE" +}; + +static const char *TGSI_DECLARES[] = +{ + "DECLARE_RANGE", + "DECLARE_MASK" +}; + +static const char *TGSI_INTERPOLATES[] = +{ + "INTERPOLATE_CONSTANT", + "INTERPOLATE_LINEAR", + "INTERPOLATE_PERSPECTIVE" +}; + +static const char *TGSI_IMMS[] = +{ + "IMM_FLOAT32" +}; + +static const char *TGSI_OPCODES[] = +{ + "OPCODE_MOV", + "OPCODE_LIT", + "OPCODE_RCP", + "OPCODE_RSQ", + "OPCODE_EXP", + "OPCODE_LOG", + "OPCODE_MUL", + "OPCODE_ADD", + "OPCODE_DP3", + "OPCODE_DP4", + "OPCODE_DST", + "OPCODE_MIN", + "OPCODE_MAX", + "OPCODE_SLT", + "OPCODE_SGE", + "OPCODE_MAD", + "OPCODE_SUB", + "OPCODE_LERP", + "OPCODE_CND", + "OPCODE_CND0", + "OPCODE_DOT2ADD", + "OPCODE_INDEX", + "OPCODE_NEGATE", + "OPCODE_FRAC", + "OPCODE_CLAMP", + "OPCODE_FLOOR", + "OPCODE_ROUND", + "OPCODE_EXPBASE2", + "OPCODE_LOGBASE2", + "OPCODE_POWER", + "OPCODE_CROSSPRODUCT", + "OPCODE_MULTIPLYMATRIX", + "OPCODE_ABS", + "OPCODE_RCC", + "OPCODE_DPH", + "OPCODE_COS", + "OPCODE_DDX", + "OPCODE_DDY", + "OPCODE_KIL", + "OPCODE_PK2H", + "OPCODE_PK2US", + "OPCODE_PK4B", + "OPCODE_PK4UB", + "OPCODE_RFL", + "OPCODE_SEQ", + "OPCODE_SFL", + "OPCODE_SGT", + "OPCODE_SIN", + "OPCODE_SLE", + "OPCODE_SNE", + "OPCODE_STR", + "OPCODE_TEX", + "OPCODE_TXD", + "OPCODE_UP2H", + "OPCODE_UP2US", + "OPCODE_UP4B", + "OPCODE_UP4UB", + "OPCODE_X2D", + "OPCODE_ARA", + "OPCODE_ARR", + "OPCODE_BRA", + "OPCODE_CAL", + "OPCODE_RET", + "OPCODE_SSG", + "OPCODE_CMP", + "OPCODE_SCS", + "OPCODE_TXB", + "OPCODE_NRM", + "OPCODE_DIV", + "OPCODE_DP2", + "OPCODE_TXL", + "OPCODE_BRK", + "OPCODE_IF", + "OPCODE_LOOP", + "OPCODE_REP", + "OPCODE_ELSE", + "OPCODE_ENDIF", + "OPCODE_ENDLOOP", + "OPCODE_ENDREP", + "OPCODE_PUSHA", + "OPCODE_POPA", + "OPCODE_CEIL", + "OPCODE_I2F", + "OPCODE_NOT", + "OPCODE_TRUNC", + "OPCODE_SHL", + "OPCODE_SHR", + "OPCODE_AND", + "OPCODE_OR", + "OPCODE_MOD", + "OPCODE_XOR", + "OPCODE_SAD", + "OPCODE_TXF", + "OPCODE_TXQ", + "OPCODE_CONT", + "OPCODE_EMIT", + "OPCODE_ENDPRIM" +}; + +static const char *TGSI_SATS[] = +{ + "SAT_NONE", + "SAT_ZERO_ONE", + "SAT_MINUS_PLUS_ONE" +}; + +static const char *TGSI_INSTRUCTION_EXTS[] = +{ + "INSTRUCTION_EXT_TYPE_NV", + "INSTRUCTION_EXT_TYPE_LABEL", + "INSTRUCTION_EXT_TYPE_TEXTURE" +}; + +static const char *TGSI_PRECISIONS[] = +{ + "PRECISION_DEFAULT", + "TGSI_PRECISION_FLOAT32", + "TGSI_PRECISION_FLOAT16", + "TGSI_PRECISION_FIXED12" +}; + +static const char *TGSI_CCS[] = +{ + "CC_GT", + "CC_EQ", + "CC_LT", + "CC_UN", + "CC_GE", + "CC_LE", + "CC_NE", + "CC_TR", + "CC_FL" +}; + +static const char *TGSI_SWIZZLES[] = +{ + "SWIZZLE_X", + "SWIZZLE_Y", + "SWIZZLE_Z", + "SWIZZLE_W" +}; + +static const char *TGSI_TEXTURES[] = +{ + "TEXTURE_UNKNOWN", + "TEXTURE_1D", + "TEXTURE_2D", + "TEXTURE_3D", + "TEXTURE_CUBE", + "TEXTURE_RECT", + "TEXTURE_SHADOW1D", + "TEXTURE_SHADOW2D", + "TEXTURE_SHADOWRECT" +}; + +static const char *TGSI_SRC_REGISTER_EXTS[] = +{ + "SRC_REGISTER_EXT_TYPE_SWZ", + "SRC_REGISTER_EXT_TYPE_MOD" +}; + +static const char *TGSI_EXTSWIZZLES[] = +{ + "EXTSWIZZLE_X", + "EXTSWIZZLE_Y", + "EXTSWIZZLE_Z", + "EXTSWIZZLE_W", + "EXTSWIZZLE_ZERO", + "EXTSWIZZLE_ONE" +}; + +static const char *TGSI_WRITEMASKS[] = +{ + "0", + "WRITEMASK_X", + "WRITEMASK_Y", + "WRITEMASK_XY", + "WRITEMASK_Z", + "WRITEMASK_XZ", + "WRITEMASK_YZ", + "WRITEMASK_XYZ", + "WRITEMASK_W", + "WRITEMASK_XW", + "WRITEMASK_YW", + "WRITEMASK_XYW", + "WRITEMASK_ZW", + "WRITEMASK_XZW", + "WRITEMASK_YZW", + "WRITEMASK_XYZW" +}; + +static const char *TGSI_DST_REGISTER_EXTS[] = +{ + "DST_REGISTER_EXT_TYPE_CONDCODE", + "DST_REGISTER_EXT_TYPE_MODULATE" +}; + +static const char *TGSI_MODULATES[] = +{ + "MODULATE_1X", + "MODULATE_2X", + "MODULATE_4X", + "MODULATE_8X", + "MODULATE_HALF", + "MODULATE_QUARTER", + "MODULATE_EIGHTH" +}; + +void +tgsi_dump( + const struct tgsi_token *tokens, + GLuint flags ) +{ + struct text_dump dump; + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + GLuint ignored = !(flags & TGSI_DUMP_NO_IGNORED); + GLuint deflt = !(flags & TGSI_DUMP_NO_DEFAULT); + + { + static GLuint counter = 0; + char buffer[64]; + + sprintf( buffer, "sbir-dump-%.4u.txt", counter++ ); + dump.file = fopen( buffer, "wt" ); + dump.tabs = 0; + } + + tgsi_parse_init( &parse, tokens ); + + TXT( "sbir-dump" ); + + CHR( '\n' ); + TXT( "\nMajorVersion: " ); + UID( parse.FullVersion.Version.MajorVersion ); + TXT( "\nMinorVersion: " ); + UID( parse.FullVersion.Version.MinorVersion ); + + CHR( '\n' ); + TXT( "\nHeaderSize: " ); + UID( parse.FullHeader.Header.HeaderSize ); + TXT( "\nBodySize : " ); + UID( parse.FullHeader.Header.BodySize ); + TXT( "\nProcessor : " ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + GLuint i; + + tgsi_parse_token( &parse ); + + CHR( '\n' ); + TXT( "\nType : " ); + ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); + if( ignored ) { + TXT( "\nSize : " ); + UID( parse.FullToken.Token.Size ); + if( deflt || parse.FullToken.Token.Extended ) { + TXT( "\nExtended : " ); + UID( parse.FullToken.Token.Extended ); + } + } + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; + + TXT( "\nFile : " ); + ENM( decl->Declaration.File, TGSI_FILES ); + TXT( "\nDeclare : " ); + ENM( decl->Declaration.Declare, TGSI_DECLARES ); + if( deflt || fd.Declaration.Interpolate != decl->Declaration.Interpolate ) { + TXT( "\nInterpolate: " ); + UID( decl->Declaration.Interpolate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Declaration.Padding ); + } + + CHR( '\n' ); + switch( decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + TXT( "\nFirst: " ); + UID( decl->u.DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->u.DeclarationRange.Last ); + break; + + case TGSI_DECLARE_MASK: + TXT( "\nMask: " ); + UIX( decl->u.DeclarationMask.Mask ); + break; + + default: + assert( 0 ); + } + + if( decl->Declaration.Interpolate ) { + CHR( '\n' ); + TXT( "\nInterpolate: " ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Interpolation.Padding ); + } + } + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + TXT( "\nDataType : " ); + ENM( parse.FullToken.FullImmediate.Immediate.DataType, TGSI_IMMS ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( parse.FullToken.FullImmediate.Immediate.Padding ); + } + + for( i = 0; i < parse.FullToken.FullImmediate.Immediate.Size - 1; i++ ) { + CHR( '\n' ); + switch( parse.FullToken.FullImmediate.Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + TXT( "\nFloat: " ); + FLT( parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + } + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction; + + TXT( "\nOpcode : " ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + if( deflt || fi.Instruction.Saturate != inst->Instruction.Saturate ) { + TXT( "\nSaturate : " ); + ENM( inst->Instruction.Saturate, TGSI_SATS ); + } + if( deflt || fi.Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { + TXT( "\nNumDstRegs : " ); + UID( inst->Instruction.NumDstRegs ); + } + if( deflt || fi.Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { + TXT( "\nNumSrcRegs : " ); + UID( inst->Instruction.NumSrcRegs ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->Instruction.Padding ); + } + + if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi.InstructionExtNv)) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi.InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { + TXT( "\nPrecision : " ); + ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); + } + if( deflt || fi.InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { + TXT( "\nCondDstIndex : " ); + UID( inst->InstructionExtNv.CondDstIndex ); + } + if( deflt || fi.InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { + TXT( "\nCondFlowIndex : " ); + UID( inst->InstructionExtNv.CondFlowIndex ); + } + if( deflt || fi.InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { + TXT( "\nCondMask : " ); + ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); + } + if( deflt || fi.InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { + TXT( "\nCondSwizzleX : " ); + ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fi.InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { + TXT( "\nCondSwizzleY : " ); + ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fi.InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ : " ); + ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fi.InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { + TXT( "\nCondSwizzleW : " ); + ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fi.InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { + TXT( "\nCondDstUpdate : " ); + UID( inst->InstructionExtNv.CondDstUpdate ); + } + if( deflt || fi.InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { + TXT( "\nCondFlowEnable: " ); + UID( inst->InstructionExtNv.CondFlowEnable ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtNv.Padding ); + if( deflt || fi.InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { + TXT( "\nExtended : " ); + UID( inst->InstructionExtNv.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi.InstructionExtLabel ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi.InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { + TXT( "\nLabel : " ); + UID( inst->InstructionExtLabel.Label ); + } + if( deflt || fi.InstructionExtLabel.Target != inst->InstructionExtLabel.Target ) { + TXT( "\nTarget : " ); + UID( inst->InstructionExtLabel.Target ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtLabel.Padding ); + if( deflt || fi.InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtLabel.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi.InstructionExtTexture ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi.InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { + TXT( "\nTexture : " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtTexture.Padding ); + if( deflt || fi.InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtTexture.Extended ); + } + } + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + struct tgsi_full_dst_register *fd = &fi.FullDstRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : " ); + ENM( dst->DstRegister.File, TGSI_FILES ); + if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { + TXT( "\nWriteMask: " ); + ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); + } + if( ignored ) { + if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( dst->DstRegister.Indirect ); + } + if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( dst->DstRegister.Dimension ); + } + } + if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { + TXT( "\nIndex : " ); + SID( dst->DstRegister.Index ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegister.Padding ); + if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegister.Extended ); + } + } + + if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { + TXT( "\nCondMask : " ); + ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { + TXT( "\nCondSwizzleX: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { + TXT( "\nCondSwizzleY: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { + TXT( "\nCondSwizzleW: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { + TXT( "\nCondSrcIndex: " ); + UID( dst->DstRegisterExtConcode.CondSrcIndex ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtConcode.Padding ); + if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegisterExtConcode.Extended ); + } + } + } + + if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { + TXT( "\nModulate: " ); + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtModulate.Padding ); + if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { + TXT( "\nExtended: " ); + UID( dst->DstRegisterExtModulate.Extended ); + } + } + } + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + struct tgsi_full_src_register *fs = &fi.FullSrcRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : "); + ENM( src->SrcRegister.File, TGSI_FILES ); + if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { + TXT( "\nSwizzleX : " ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { + TXT( "\nSwizzleY : " ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { + TXT( "\nSwizzleZ : " ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { + TXT( "\nSwizzleW : " ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegister.Negate ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( src->SrcRegister.Indirect ); + } + if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( src->SrcRegister.Dimension ); + } + } + if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { + TXT( "\nIndex : " ); + SID( src->SrcRegister.Index ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegister.Extended ); + } + } + + if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { + TXT( "\nExtSwizzleX: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { + TXT( "\nExtSwizzleY: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { + TXT( "\nExtSwizzleZ: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { + TXT( "\nExtSwizzleW: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { + TXT( "\nNegateX : " ); + UID( src->SrcRegisterExtSwz.NegateX ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { + TXT( "\nNegateY : " ); + UID( src->SrcRegisterExtSwz.NegateY ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { + TXT( "\nNegateZ : " ); + UID( src->SrcRegisterExtSwz.NegateZ ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { + TXT( "\nNegateW : " ); + UID( src->SrcRegisterExtSwz.NegateW ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) { + TXT( "\nExtDivide : " ); + ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtSwz.Padding ); + if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtSwz.Extended ); + } + } + } + + if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { + TXT( "\nComplement: " ); + UID( src->SrcRegisterExtMod.Complement ); + } + if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { + TXT( "\nBias : " ); + UID( src->SrcRegisterExtMod.Bias ); + } + if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { + TXT( "\nScale2X : " ); + UID( src->SrcRegisterExtMod.Scale2X ); + } + if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { + TXT( "\nAbsolute : " ); + UID( src->SrcRegisterExtMod.Absolute ); + } + if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegisterExtMod.Negate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtMod.Padding ); + if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtMod.Extended ); + } + } + } + } + } + break; + + default: + assert( 0 ); + } + } + + tgsi_parse_free( &parse ); + + fclose( dump.file ); +} + diff --git a/src/mesa/pipe/tgsi/core/tgsi_dump.h b/src/mesa/pipe/tgsi/core/tgsi_dump.h new file mode 100644 index 0000000000..dc34a840de --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_dump.h @@ -0,0 +1,22 @@ +#if !defined TGSI_DUMP_H +#define TGSI_DUMP_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +#define TGSI_DUMP_VERBOSE 0 +#define TGSI_DUMP_NO_IGNORED 1 +#define TGSI_DUMP_NO_DEFAULT 2 + +void +tgsi_dump( + const struct tgsi_token *tokens, + GLuint flags ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_DUMP_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.c b/src/mesa/pipe/tgsi/core/tgsi_exec.c new file mode 100644 index 0000000000..189a41167a --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_exec.c @@ -0,0 +1,2193 @@ +#include "tgsi_platform.h" +#include "tgsi_core.h" + +#define TILE_BOTTOM_LEFT 0 +#define TILE_BOTTOM_RIGHT 1 +#define TILE_TOP_LEFT 2 +#define TILE_TOP_RIGHT 3 + +#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I +#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C +#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I +#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C +#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I +#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C +#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I +#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C +#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C +#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I +#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C +#define TEMP_128_I TGSI_EXEC_TEMP_128_I +#define TEMP_128_C TGSI_EXEC_TEMP_128_C +#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I +#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C +#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I +#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C +#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I +#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C +#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I +#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +#define FOR_EACH_CHANNEL(CHAN)\ + for (CHAN = 0; CHAN < 4; CHAN++) + +#define IS_CHANNEL_ENABLED(INST, CHAN)\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IS_CHANNEL_ENABLED2(INST, CHAN)\ + ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) + +#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED2( INST, CHAN )) + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + struct tgsi_token *tokens ) +{ + GLuint i; + struct tgsi_parse_context parse; + + mach->Tokens = tokens; + + tgsi_parse_init (&parse, mach->Tokens); + mach->Processor = parse.FullHeader.Processor.Processor; + tgsi_parse_free (&parse); + + mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); + mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; + +#if XXX_SSE + tgsi_emit_sse (tokens, + &mach->Function); +#endif + + /* Setup constants. */ + for( i = 0; i < 4; i++ ) { + mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; + mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; + mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; + mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; + mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; + mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; + mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; + mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; + } +} + +void +tgsi_exec_prepare( + struct tgsi_exec_machine *mach, + struct tgsi_exec_labels *labels ) +{ + struct tgsi_parse_context parse; + + mach->ImmLimit = 0; + labels->count = 0; + + tgsi_parse_init( &parse, mach->Tokens ); + while( !tgsi_parse_end_of_tokens( &parse ) ) { + GLuint pointer = parse.Position; + GLuint i; + tgsi_parse_token( &parse ); + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + assert( (parse.FullToken.FullImmediate.Immediate.Size - 1) % 4 == 0 ); + assert( mach->ImmLimit + (parse.FullToken.FullImmediate.Immediate.Size - 1) / 4 <= 256 ); + for( i = 0; i < parse.FullToken.FullImmediate.Immediate.Size - 1; i++ ) { + mach->Imms[mach->ImmLimit + i / 4][i % 4] = parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } + mach->ImmLimit += (parse.FullToken.FullImmediate.Immediate.Size - 1) / 4; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + if( parse.FullToken.FullInstruction.InstructionExtLabel.Label && + parse.FullToken.FullInstruction.InstructionExtLabel.Target ) { + assert( labels->count < 128 ); + labels->labels[labels->count][0] = parse.FullToken.FullInstruction.InstructionExtLabel.Label; + labels->labels[labels->count][1] = pointer; + labels->count++; + } + break; + default: + assert( 0 ); + } + } + tgsi_parse_free (&parse); +} + +void +tgsi_exec_machine_run( + struct tgsi_exec_machine *mach ) +{ + struct tgsi_exec_labels labels; + + tgsi_exec_prepare( mach, &labels ); + tgsi_exec_machine_run2( mach, &labels ); +} + +static void +micro_abs( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) fabs( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) fabs( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) fabs( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) fabs( (GLdouble) src->f[3] ); +} + +static void +micro_add( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] + src1->f[0]; + dst->f[1] = src0->f[1] + src1->f[1]; + dst->f[2] = src0->f[2] + src1->f[2]; + dst->f[3] = src0->f[3] + src1->f[3]; +} + +static void +micro_iadd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] + src1->i[0]; + dst->i[1] = src0->i[1] + src1->i[1]; + dst->i[2] = src0->i[2] + src1->i[2]; + dst->i[3] = src0->i[3] + src1->i[3]; +} + +static void +micro_and( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] & src1->u[0]; + dst->u[1] = src0->u[1] & src1->u[1]; + dst->u[2] = src0->u[2] & src1->u[2]; + dst->u[3] = src0->u[3] & src1->u[3]; +} + +static void +micro_ceil( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) ceil( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) ceil( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) ceil( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) ceil( (GLdouble) src->f[3] ); +} + +static void +micro_cos( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) cos( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) cos( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) cos( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) cos( (GLdouble) src->f[3] ); +} + +static void +micro_div( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] / src1->f[0]; + dst->f[1] = src0->f[1] / src1->f[1]; + dst->f[2] = src0->f[2] / src1->f[2]; + dst->f[3] = src0->f[3] / src1->f[3]; +} + +static void +micro_udiv( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] / src1->u[0]; + dst->u[1] = src0->u[1] / src1->u[1]; + dst->u[2] = src0->u[2] / src1->u[2]; + dst->u[3] = src0->u[3] / src1->u[3]; +} + +static void +micro_eq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ieq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_exp2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) pow( 2.0, (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) pow( 2.0, (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) pow( 2.0, (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) pow( 2.0, (GLdouble) src->f[3] ); +} + +static void +micro_f2it( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = (GLint) src->f[0]; + dst->i[1] = (GLint) src->f[1]; + dst->i[2] = (GLint) src->f[2]; + dst->i[3] = (GLint) src->f[3]; +} + +static void +micro_f2ut( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = (GLuint) src->f[0]; + dst->u[1] = (GLuint) src->f[1]; + dst->u[2] = (GLuint) src->f[2]; + dst->u[3] = (GLuint) src->f[3]; +} + +static void +micro_flr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) floor( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) floor( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) floor( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) floor( (GLdouble) src->f[3] ); +} + +static void +micro_frc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = src->f[0] - (GLfloat) floor( (GLdouble) src->f[0] ); + dst->f[1] = src->f[1] - (GLfloat) floor( (GLdouble) src->f[1] ); + dst->f[2] = src->f[2] - (GLfloat) floor( (GLdouble) src->f[2] ); + dst->f[3] = src->f[3] - (GLfloat) floor( (GLdouble) src->f[3] ); +} + +static void +micro_i2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) src->i[0]; + dst->f[1] = (GLfloat) src->i[1]; + dst->f[2] = (GLfloat) src->i[2]; + dst->f[3] = (GLfloat) src->i[3]; +} + +static void +micro_lg2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) log( (GLdouble) src->f[0] ) * 1.442695f; + dst->f[1] = (GLfloat) log( (GLdouble) src->f[1] ) * 1.442695f; + dst->f[2] = (GLfloat) log( (GLdouble) src->f[2] ) * 1.442695f; + dst->f[3] = (GLfloat) log( (GLdouble) src->f[3] ) * 1.442695f; +} + +static void +micro_lt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ilt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_ult( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; +} + +static void +micro_max( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_min( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_umod( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] % src1->u[0]; + dst->u[1] = src0->u[1] % src1->u[1]; + dst->u[2] = src0->u[2] % src1->u[2]; + dst->u[3] = src0->u[3] % src1->u[3]; +} + +static void +micro_mul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] * src1->f[0]; + dst->f[1] = src0->f[1] * src1->f[1]; + dst->f[2] = src0->f[2] * src1->f[2]; + dst->f[3] = src0->f[3] * src1->f[3]; +} + +static void +micro_imul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] * src1->i[0]; + dst->i[1] = src0->i[1] * src1->i[1]; + dst->i[2] = src0->i[2] * src1->i[2]; + dst->i[3] = src0->i[3] * src1->i[3]; +} + +static void +micro_imul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->i[0] = src0->i[0] * src1->i[0]; + dst1->i[1] = src0->i[1] * src1->i[1]; + dst1->i[2] = src0->i[2] * src1->i[2]; + dst1->i[3] = src0->i[3] * src1->i[3]; + dst0->i[0] = 0; + dst0->i[1] = 0; + dst0->i[2] = 0; + dst0->i[3] = 0; +} + +static void +micro_umul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->u[0] = src0->u[0] * src1->u[0]; + dst1->u[1] = src0->u[1] * src1->u[1]; + dst1->u[2] = src0->u[2] * src1->u[2]; + dst1->u[3] = src0->u[3] * src1->u[3]; + dst0->u[0] = 0; + dst0->u[1] = 0; + dst0->u[2] = 0; + dst0->u[3] = 0; +} + +static void +micro_movc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2 ) +{ + dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; + dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; + dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; + dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; +} + +static void +micro_neg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = -src->f[0]; + dst->f[1] = -src->f[1]; + dst->f[2] = -src->f[2]; + dst->f[3] = -src->f[3]; +} + +static void +micro_ineg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = -src->i[0]; + dst->i[1] = -src->i[1]; + dst->i[2] = -src->i[2]; + dst->i[3] = -src->i[3]; +} + +static void +micro_not( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = ~src->u[0]; + dst->u[1] = ~src->u[1]; + dst->u[2] = ~src->u[2]; + dst->u[3] = ~src->u[3]; +} + +static void +micro_or( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] | src1->u[0]; + dst->u[1] = src0->u[1] | src1->u[1]; + dst->u[2] = src0->u[2] | src1->u[2]; + dst->u[3] = src0->u[3] | src1->u[3]; +} + +static void +micro_pow( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = (GLfloat) pow( (GLdouble) src0->f[0], (GLdouble) src1->f[0] ); + dst->f[1] = (GLfloat) pow( (GLdouble) src0->f[1], (GLdouble) src1->f[1] ); + dst->f[2] = (GLfloat) pow( (GLdouble) src0->f[2], (GLdouble) src1->f[2] ); + dst->f[3] = (GLfloat) pow( (GLdouble) src0->f[3], (GLdouble) src1->f[3] ); +} + +static void +micro_rnd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) floor( (GLdouble) (src->f[0] + 0.5f) ); + dst->f[1] = (GLfloat) floor( (GLdouble) (src->f[1] + 0.5f) ); + dst->f[2] = (GLfloat) floor( (GLdouble) (src->f[2] + 0.5f) ); + dst->f[3] = (GLfloat) floor( (GLdouble) (src->f[3] + 0.5f) ); +} + +static void +micro_shl( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] << src1->i[0]; + dst->i[1] = src0->i[1] << src1->i[1]; + dst->i[2] = src0->i[2] << src1->i[2]; + dst->i[3] = src0->i[3] << src1->i[3]; +} + +static void +micro_ishr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] >> src1->i[0]; + dst->i[1] = src0->i[1] >> src1->i[1]; + dst->i[2] = src0->i[2] >> src1->i[2]; + dst->i[3] = src0->i[3] >> src1->i[3]; +} + +static void +micro_ushr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] >> src1->u[0]; + dst->u[1] = src0->u[1] >> src1->u[1]; + dst->u[2] = src0->u[2] >> src1->u[2]; + dst->u[3] = src0->u[3] >> src1->u[3]; +} + +static void +micro_sin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) sin( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) sin( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) sin( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) sin( (GLdouble) src->f[3] ); +} + +static void +micro_sqrt( union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) sqrt( (GLdouble) src->f[0] ); + dst->f[1] = (GLfloat) sqrt( (GLdouble) src->f[1] ); + dst->f[2] = (GLfloat) sqrt( (GLdouble) src->f[2] ); + dst->f[3] = (GLfloat) sqrt( (GLdouble) src->f[3] ); +} + +static void +micro_sub( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] - src1->f[0]; + dst->f[1] = src0->f[1] - src1->f[1]; + dst->f[2] = src0->f[2] - src1->f[2]; + dst->f[3] = src0->f[3] - src1->f[3]; +} + +static void +micro_u2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (GLfloat) src->u[0]; + dst->f[1] = (GLfloat) src->u[1]; + dst->f[2] = (GLfloat) src->u[2]; + dst->f[3] = (GLfloat) src->u[3]; +} + +static void +micro_xor( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] ^ src1->u[0]; + dst->u[1] = src0->u[1] ^ src1->u[1]; + dst->u[2] = src0->u[2] ^ src1->u[2]; + dst->u[3] = src0->u[3] ^ src1->u[3]; +} + +static void +fetch_src_file_channel( + const struct tgsi_exec_machine *mach, + const GLuint file, + const GLuint swizzle, + const union tgsi_exec_channel *index, + union tgsi_exec_channel *chan ) +{ + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( file ) { + case TGSI_FILE_CONSTANT: + chan->f[0] = mach->Consts[index->i[0]][swizzle]; + chan->f[1] = mach->Consts[index->i[1]][swizzle]; + chan->f[2] = mach->Consts[index->i[2]][swizzle]; + chan->f[3] = mach->Consts[index->i[3]][swizzle]; + break; + + case TGSI_FILE_INPUT: + chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_TEMPORARY: + chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_IMMEDIATE: + assert( index->i[0] < (GLint) mach->ImmLimit ); + chan->f[0] = mach->Imms[index->i[0]][swizzle]; + assert( index->i[1] < (GLint) mach->ImmLimit ); + chan->f[1] = mach->Imms[index->i[1]][swizzle]; + assert( index->i[2] < (GLint) mach->ImmLimit ); + chan->f[2] = mach->Imms[index->i[2]][swizzle]; + assert( index->i[3] < (GLint) mach->ImmLimit ); + chan->f[3] = mach->Imms[index->i[3]][swizzle]; + break; + + case TGSI_FILE_ADDRESS: + chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; + break; + + case TGSI_EXTSWIZZLE_ONE: + *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; + break; + + default: + assert( 0 ); + } +} + +static void +fetch_source( + const struct tgsi_exec_machine *mach, + union tgsi_exec_channel *chan, + const struct tgsi_full_src_register *reg, + const GLuint chan_index ) +{ + union tgsi_exec_channel index; + GLuint swizzle; + + index.i[0] = + index.i[1] = + index.i[2] = + index.i[3] = reg->SrcRegister.Index; + + if (reg->SrcRegister.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + + if( reg->SrcRegister.Dimension ) { + switch( reg->SrcRegister.File ) { + case TGSI_FILE_INPUT: + index.i[0] *= 17; + index.i[1] *= 17; + index.i[2] *= 17; + index.i[3] *= 17; + break; + case TGSI_FILE_CONSTANT: + index.i[0] *= 4096; + index.i[1] *= 4096; + index.i[2] *= 4096; + index.i[3] *= 4096; + break; + default: + assert( 0 ); + } + + index.i[0] += reg->SrcRegisterDim.Index; + index.i[1] += reg->SrcRegisterDim.Index; + index.i[2] += reg->SrcRegisterDim.Index; + index.i[3] += reg->SrcRegisterDim.Index; + + if (reg->SrcRegisterDim.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterDimInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterDimInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + } + + swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + fetch_src_file_channel( + mach, + reg->SrcRegister.File, + swizzle, + &index, + chan ); + + switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { + case TGSI_UTIL_SIGN_CLEAR: + micro_abs( chan, chan ); + break; + + case TGSI_UTIL_SIGN_SET: + micro_abs( chan, chan ); + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } +} + +static void +store_dest( + struct tgsi_exec_machine *mach, + const union tgsi_exec_channel *chan, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + GLuint chan_index ) +{ + union tgsi_exec_channel *dst; + + switch( reg->DstRegister.File ) { + case TGSI_FILE_NULL: + return; + + case TGSI_FILE_OUTPUT: + dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_TEMPORARY: + dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_ADDRESS: + dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; + break; + + default: + assert( 0 ); + } + + switch (inst->Instruction.Saturate) + { + case TGSI_SAT_NONE: + *dst = *chan; + break; + + case TGSI_SAT_ZERO_ONE: + micro_lt( dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], chan ); + micro_lt( dst, chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + + default: + assert( 0 ); + } +} + +#define FETCH(VAL,INDEX,CHAN)\ + fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) + +#define STORE(VAL,INDEX,CHAN)\ + store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN) + +static void +exec_kil (struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + GLuint uniquemask; + GLuint chan_index; + GLuint kilmask = 0; + union tgsi_exec_channel r[1]; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + for (chan_index = 0; chan_index < 4; chan_index++) + { + GLuint swizzle; + GLuint i; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle ( + &inst->FullSrcRegisters[0], + chan_index); + + /* check if the component has not been already tested */ + if (uniquemask & (1 << swizzle)) + continue; + uniquemask |= 1 << swizzle; + + FETCH(&r[0], 0, chan_index); + for (i = 0; i < 4; i++) + if (r[0].f[i] < 0.0f) + kilmask |= 1 << (i * 4); + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + +#if MESA +/* + * Fetch a texel using S texture coordinate. + */ +static void +fetch_texel_1d( GLcontext *ctx, + struct tgsi_sampler_state *sampler, + const union tgsi_exec_channel *s, + GLuint unit, + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint fragment_index; + GLfloat stpq[4][4]; + GLfloat lambdas[4]; + GLchan rgba[4][4]; + + for (fragment_index = 0; fragment_index < 4; fragment_index++) + { + stpq[fragment_index][0] = s->f[fragment_index]; + } + + if (sampler->NeedLambda) + { + GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT]; + GLfloat dsdy = s->f[TILE_TOP_LEFT] - s->f[TILE_BOTTOM_LEFT]; + + GLfloat rho, lambda; + + dsdx = FABSF(dsdx); + dsdy = FABSF(dsdy); + + rho = MAX2(dsdx, dsdy) * sampler->ImageWidth; + + lambda = LOG2(rho); + + if (sampler->NeedLodBias) + lambda += sampler->LodBias; + + if (sampler->NeedLambdaClamp) + lambda = CLAMP(lambda, sampler->MinLod, sampler->MaxLod); + + /* XXX: Use the same lambda value throughout the tile. Could + * end up with four unique values by recalculating partial + * derivs in the other row and column, and calculating lambda + * using the dx and dy values appropriate for each fragment in + * the tile. + */ + lambdas[0] = + lambdas[1] = + lambdas[2] = + lambdas[3] = lambda; + } + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit] (ctx, + ctx->Texture.Unit[unit]._Current, + 4, + (const GLfloat (*)[4])stpq, + lambdas, + rgba); + + for (fragment_index = 0; fragment_index < 4; fragment_index++) + { + r->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][0]); + g->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][1]); + b->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][2]); + a->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][3]); + } +} + +/* + * Fetch a texel using ST texture coordinates. + */ +static void +fetch_texel_2d( GLcontext *ctx, + struct tgsi_sampler_state *sampler, + const union tgsi_exec_channel *s, + const union tgsi_exec_channel *t, + GLuint unit, + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + SWcontext *swrast = SWRAST_CONTEXT( ctx ); + GLuint fragment_index; + GLfloat stpq[4][4]; + GLfloat lambdas[4]; + GLchan rgba[4][4]; + + for (fragment_index = 0; fragment_index < 4; fragment_index++) { + stpq[fragment_index][0] = s->f[fragment_index]; + stpq[fragment_index][1] = t->f[fragment_index]; + } + + if (sampler->NeedLambda) { + GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT]; + GLfloat dsdy = s->f[TILE_TOP_LEFT] - s->f[TILE_BOTTOM_LEFT]; + + GLfloat dtdx = t->f[TILE_BOTTOM_RIGHT] - t->f[TILE_BOTTOM_LEFT]; + GLfloat dtdy = t->f[TILE_TOP_LEFT] - t->f[TILE_BOTTOM_LEFT]; + + GLfloat maxU, maxV, rho, lambda; + + dsdx = FABSF( dsdx ); + dsdy = FABSF( dsdy ); + dtdx = FABSF( dtdx ); + dtdy = FABSF( dtdy ); + + maxU = MAX2( dsdx, dsdy ) * sampler->ImageWidth; + maxV = MAX2( dtdx, dtdy ) * sampler->ImageHeight; + + rho = MAX2( maxU, maxV ); + + lambda = LOG2( rho ); + + if (sampler->NeedLodBias) + lambda += sampler->LodBias; + + if (sampler->NeedLambdaClamp) + lambda = CLAMP( + lambda, + sampler->MinLod, + sampler->MaxLod ); + + /* XXX: Use the same lambda value throughout the tile. Could + * end up with four unique values by recalculating partial + * derivs in the other row and column, and calculating lambda + * using the dx and dy values appropriate for each fragment in + * the tile. + */ + lambdas[0] = + lambdas[1] = + lambdas[2] = + lambdas[3] = lambda; + } + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit]( + ctx, + ctx->Texture.Unit[unit]._Current, + 4, + (const GLfloat (*)[4]) stpq, + lambdas, + rgba ); + + for (fragment_index = 0; fragment_index < 4; fragment_index++) { + r->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][0] ); + g->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][1] ); + b->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][2] ); + a->f[fragment_index] = CHAN_TO_FLOAT( rgba[fragment_index][3] ); + } +} + +/* + * Fetch a texel using STR texture coordinates. + */ +static void +fetch_texel_3d( GLcontext *ctx, + struct tgsi_sampler_state *sampler, + const union tgsi_exec_channel *s, + const union tgsi_exec_channel *t, + const union tgsi_exec_channel *p, + GLuint unit, + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint fragment_index; + GLfloat stpq[4][4]; + GLfloat lambdas[4]; + GLchan rgba[4][4]; + + for (fragment_index = 0; fragment_index < 4; fragment_index++) + { + stpq[fragment_index][0] = s->f[fragment_index]; + stpq[fragment_index][1] = t->f[fragment_index]; + stpq[fragment_index][2] = p->f[fragment_index]; + } + + if (sampler->NeedLambda) + { + GLfloat dsdx = s->f[TILE_BOTTOM_RIGHT] - s->f[TILE_BOTTOM_LEFT]; + GLfloat dsdy = s->f[TILE_TOP_LEFT] - s->f[TILE_BOTTOM_LEFT]; + + GLfloat dtdx = t->f[TILE_BOTTOM_RIGHT] - t->f[TILE_BOTTOM_LEFT]; + GLfloat dtdy = t->f[TILE_TOP_LEFT] - t->f[TILE_BOTTOM_LEFT]; + + GLfloat dpdx = p->f[TILE_BOTTOM_RIGHT] - p->f[TILE_BOTTOM_LEFT]; + GLfloat dpdy = p->f[TILE_TOP_LEFT] - p->f[TILE_BOTTOM_LEFT]; + + GLfloat maxU, maxV, maxW, rho, lambda; + + dsdx = FABSF(dsdx); + dsdy = FABSF(dsdy); + dtdx = FABSF(dtdx); + dtdy = FABSF(dtdy); + dpdx = FABSF(dpdx); + dpdy = FABSF(dpdy); + + maxU = MAX2(dsdx, dsdy) * sampler->ImageWidth; + maxV = MAX2(dtdx, dtdy) * sampler->ImageHeight; + maxW = MAX2(dpdx, dpdy) * sampler->ImageDepth; + + rho = MAX2(maxU, MAX2(maxV, maxW)); + + lambda = LOG2(rho); + + if (sampler->NeedLodBias) + lambda += sampler->LodBias; + + if (sampler->NeedLambdaClamp) + lambda = CLAMP(lambda, sampler->MinLod, sampler->MaxLod); + + /* XXX: Use the same lambda value throughout the tile. Could + * end up with four unique values by recalculating partial + * derivs in the other row and column, and calculating lambda + * using the dx and dy values appropriate for each fragment in + * the tile. + */ + lambdas[0] = + lambdas[1] = + lambdas[2] = + lambdas[3] = lambda; + } + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit] (ctx, + ctx->Texture.Unit[unit]._Current, + 4, + (const GLfloat (*)[4])stpq, + lambdas, + rgba); + + for (fragment_index = 0; fragment_index < 4; fragment_index++) + { + r->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][0]); + g->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][1]); + b->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][2]); + a->f[fragment_index] = CHAN_TO_FLOAT(rgba[fragment_index][3]); + } +} +#endif + +static GLuint +map_label( + GLuint label, + struct tgsi_exec_labels *labels ) +{ + GLuint i; + + for( i = 0; i < labels->count; i++ ) { + if( labels->labels[i][0] == label ) { + return labels->labels[i][1]; + } + } + assert( 0 ); + return 0; +} + +static void +exec_instruction( + struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + struct tgsi_exec_labels *labels, + GLuint *programCounter ) +{ +#if MESA + GET_CURRENT_CONTEXT(ctx); +#endif + GLuint chan_index; + union tgsi_exec_channel r[8]; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_f2it( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_X ); + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[1], 0, CHAN_Y ); + micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + + FETCH( &r[2], 0, CHAN_W ); + micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); + micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); + micro_pow( &r[1], &r[1], &r[2] ); + micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Z ); + } + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( &r[0], 0, CHAN_X ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( &r[0], 0, CHAN_X ); + micro_sqrt( &r[0], &r[0] ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + assert (0); + break; + + case TGSI_OPCODE_LOG: + assert (0); + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_mul( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Z ); + FETCH( &r[2], 1, CHAN_Z ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_W); + FETCH(&r[2], 1, CHAN_W); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + FETCH( &r[0], 0, CHAN_Y ); + FETCH( &r[1], 1, CHAN_Y); + micro_mul( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_Z ); + STORE( &r[0], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + FETCH( &r[0], 1, CHAN_W ); + STORE( &r[0], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_mul( &r[0], &r[0], &r[1] ); + FETCH( &r[1], 2, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_sub( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_sub( &r[1], &r[1], &r[2] ); + micro_mul( &r[0], &r[0], &r[1] ); + micro_add( &r[0], &r[0], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_CND: + assert (0); + break; + + case TGSI_OPCODE_CND0: + assert (0); + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + assert (0); + break; + + case TGSI_OPCODE_INDEX: + assert (0); + break; + + case TGSI_OPCODE_NEGATE: + assert (0); + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_frc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + assert (0); + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_flr( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_rnd( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH(&r[0], 0, CHAN_X); + + micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( &r[0], 0, CHAN_X ); + micro_lg2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_pow( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + FETCH(&r[0], 0, CHAN_Y); + FETCH(&r[1], 1, CHAN_Z); + + micro_mul( &r[2], &r[0], &r[1] ); + + FETCH(&r[3], 0, CHAN_Z); + FETCH(&r[4], 1, CHAN_Y); + + micro_mul( &r[5], &r[3], &r[4] ); + micro_sub( &r[2], &r[2], &r[5] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[2], 0, CHAN_X ); + } + + FETCH(&r[2], 1, CHAN_X); + + micro_mul( &r[3], &r[3], &r[2] ); + + FETCH(&r[5], 0, CHAN_X); + + micro_mul( &r[1], &r[1], &r[5] ); + micro_sub( &r[3], &r[3], &r[1] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + STORE( &r[3], 0, CHAN_Y ); + } + + micro_mul( &r[5], &r[5], &r[4] ); + micro_mul( &r[0], &r[0], &r[2] ); + micro_sub( &r[5], &r[5], &r[0] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[5], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + assert (0); + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + + micro_abs( &r[0], &r[0] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_RCC: + assert (0); + break; + + case TGSI_OPCODE_DPH: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 1, CHAN_W); + + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH(&r[0], 0, CHAN_X); + + micro_cos( &r[0], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + assert (0); + break; + + case TGSI_OPCODE_DDY: + assert (0); + break; + + case TGSI_OPCODE_KIL: + exec_kil (mach, inst); + break; + + case TGSI_OPCODE_PK2H: + assert (0); + break; + + case TGSI_OPCODE_PK2US: + assert (0); + break; + + case TGSI_OPCODE_PK4B: + assert (0); + break; + + case TGSI_OPCODE_PK4UB: + assert (0); + break; + + case TGSI_OPCODE_RFL: + assert (0); + break; + + case TGSI_OPCODE_SEQ: + assert (0); + break; + + case TGSI_OPCODE_SFL: + assert (0); + break; + + case TGSI_OPCODE_SGT: + assert (0); + break; + + case TGSI_OPCODE_SIN: + FETCH(&r[0], 0, CHAN_X); + + micro_sin( &r[0], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + assert (0); + break; + + case TGSI_OPCODE_SNE: + assert (0); + break; + + case TGSI_OPCODE_STR: + assert (0); + break; + + case TGSI_OPCODE_TEX: + + switch (inst->InstructionExtTexture.Texture) + { + case TGSI_TEXTURE_1D: + + FETCH(&r[0], 0, CHAN_X); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) + { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[1], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[1] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } +#if MESA + fetch_texel_1d (ctx, + &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index], + &r[0], + inst->FullSrcRegisters[1].SrcRegister.Index, + &r[0], &r[1], &r[2], &r[3]); +#endif + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) + { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[2], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[2] ); + micro_div( &r[1], &r[1], &r[2] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + +#if MESA + fetch_texel_2d (ctx, + &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index], + &r[0], &r[1], + inst->FullSrcRegisters[1].SrcRegister.Index, + &r[0], &r[1], &r[2], &r[3]); +#endif + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) + { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + +#if MESA + fetch_texel_3d (ctx, + &mach->Samplers[inst->FullSrcRegisters[1].SrcRegister.Index], + &r[0], &r[1], &r[2], + inst->FullSrcRegisters[1].SrcRegister.Index, + &r[0], &r[1], &r[2], &r[3]); +#endif + break; + + default: + assert (0); + } + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TXD: + assert (0); + break; + + case TGSI_OPCODE_UP2H: + assert (0); + break; + + case TGSI_OPCODE_UP2US: + assert (0); + break; + + case TGSI_OPCODE_UP4B: + assert (0); + break; + + case TGSI_OPCODE_UP4UB: + assert (0); + break; + + case TGSI_OPCODE_X2D: + assert (0); + break; + + case TGSI_OPCODE_ARA: + assert (0); + break; + + case TGSI_OPCODE_ARR: + assert (0); + break; + + case TGSI_OPCODE_BRA: + assert (0); + break; + + case TGSI_OPCODE_CAL: + assert (0); + break; + + case TGSI_OPCODE_RET: + /* XXX: end of shader! */ + /*assert (0);*/ + break; + + case TGSI_OPCODE_SSG: + assert (0); + break; + + case TGSI_OPCODE_CMP: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SCS: + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( &r[0], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + micro_cos( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + micro_sin( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_Y ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_TXB: + assert (0); + break; + + case TGSI_OPCODE_NRM: + assert (0); + break; + + case TGSI_OPCODE_DIV: + assert( 0 ); + break; + + case TGSI_OPCODE_DP2: + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TXL: + assert (0); + break; + + case TGSI_OPCODE_BRK: + assert (0); + break; + + case TGSI_OPCODE_IF: + assert (0); + break; + + case TGSI_OPCODE_LOOP: + assert (0); + break; + + case TGSI_OPCODE_REP: + assert (0); + break; + + case TGSI_OPCODE_ELSE: + assert (0); + break; + + case TGSI_OPCODE_ENDIF: + assert (0); + break; + + case TGSI_OPCODE_ENDLOOP: + assert (0); + break; + + case TGSI_OPCODE_ENDREP: + assert (0); + break; + + case TGSI_OPCODE_PUSHA: + assert (0); + break; + + case TGSI_OPCODE_POPA: + assert (0); + break; + + case TGSI_OPCODE_CEIL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ceil( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_I2F: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_i2f( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_NOT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_not( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TRUNC: + assert (0); + break; + + case TGSI_OPCODE_SHL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_shl( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ishr( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_AND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_and( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_OR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_or( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOD: + assert (0); + break; + + case TGSI_OPCODE_XOR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_xor( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SAD: + assert (0); + break; + + case TGSI_OPCODE_TXF: + assert (0); + break; + + case TGSI_OPCODE_TXQ: + assert (0); + break; + + case TGSI_OPCODE_CONT: + assert (0); + break; + + case TGSI_OPCODE_EMIT: + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; + break; + + case TGSI_OPCODE_ENDPRIM: + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; + break; + + default: + assert( 0 ); + } +} + + +#if !defined(XSTDCALL) +#if defined(WIN32) +#define XSTDCALL __stdcall +#else +#define XSTDCALL +#endif +#endif + +typedef void (XSTDCALL *fp_function) (const struct tgsi_exec_vector *input, + struct tgsi_exec_vector *output, + GLfloat (*constant)[4], + struct tgsi_exec_vector *temporary); + +void +tgsi_exec_machine_run2( + struct tgsi_exec_machine *mach, + struct tgsi_exec_labels *labels ) +{ +#if MESA + GET_CURRENT_CONTEXT(ctx); + GLuint i; +#endif + +#if XXX_SSE + fp_function function; + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + + function = (fp_function) x86_get_func (&mach->Function); + + function (mach->Inputs, + mach->Outputs, + mach->Consts, + mach->Temps); +#else + struct tgsi_parse_context parse; + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; + + if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; + mach->Primitives[0] = 0; + } + + tgsi_parse_init( &parse, mach->Tokens ); + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + exec_instruction( mach, &parse.FullToken.FullInstruction, labels, &parse.Position ); + break; + default: + assert( 0 ); + } + } + tgsi_parse_free (&parse); +#endif + +#if MESA + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { + /* + * Scale back depth component. + */ + for (i = 0; i < 4; i++) + mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; + } +#endif +} + diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.h b/src/mesa/pipe/tgsi/core/tgsi_exec.h new file mode 100644 index 0000000000..abce6ee924 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_exec.h @@ -0,0 +1,137 @@ +#if !defined TGSI_EXEC_H +#define TGSI_EXEC_H + +#if 0 +#include "x86/rtasm/x86sse.h" +#endif + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +union tgsi_exec_channel +{ + GLfloat f[4]; + GLint i[4]; + GLuint u[4]; +}; + +struct tgsi_exec_vector +{ + union tgsi_exec_channel xyzw[4]; +}; + +struct tgsi_sampler_state +{ + GLboolean NeedLambda; + GLboolean NeedLodBias; /* if NeedLambda */ + GLboolean NeedLambdaClamp; /* if NeedLambda */ + GLfloat LodBias; /* if NeedLodBias */ + GLfloat MinLod; /* if NeedLambdaClamp */ + GLfloat MaxLod; /* if NeedLambdaClamp */ + GLfloat ImageWidth; + GLfloat ImageHeight; + GLfloat ImageDepth; +}; + +struct tgsi_exec_labels +{ + GLuint labels[128][2]; + GLuint count; +}; + +#define TGSI_EXEC_TEMP_00000000_I 32 +#define TGSI_EXEC_TEMP_00000000_C 0 + +#define TGSI_EXEC_TEMP_7FFFFFFF_I 32 +#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 + +#define TGSI_EXEC_TEMP_80000000_I 32 +#define TGSI_EXEC_TEMP_80000000_C 2 + +#define TGSI_EXEC_TEMP_FFFFFFFF_I 32 +#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 + +#define TGSI_EXEC_TEMP_ONE_I 33 +#define TGSI_EXEC_TEMP_ONE_C 0 + +#define TGSI_EXEC_TEMP_TWO_I 33 +#define TGSI_EXEC_TEMP_TWO_C 1 + +#define TGSI_EXEC_TEMP_128_I 33 +#define TGSI_EXEC_TEMP_128_C 2 + +#define TGSI_EXEC_TEMP_MINUS_128_I 33 +#define TGSI_EXEC_TEMP_MINUS_128_C 3 + +#define TGSI_EXEC_TEMP_KILMASK_I 34 +#define TGSI_EXEC_TEMP_KILMASK_C 0 + +#define TGSI_EXEC_TEMP_OUTPUT_I 34 +#define TGSI_EXEC_TEMP_OUTPUT_C 1 + +#define TGSI_EXEC_TEMP_PRIMITIVE_I 34 +#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 + +#define TGSI_EXEC_TEMP_R0 35 + +#define TGSI_EXEC_NUM_TEMPS (32 + 4) +#define TGSI_EXEC_NUM_ADDRS 1 + +struct tgsi_exec_machine +{ + /* + * 32 program temporaries + * 4 internal temporaries + * 1 address + * 1 temporary of padding to align to 16 bytes + */ + struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1]; + + /* + * This will point to _Temps after aligning to 16B boundary. + */ + struct tgsi_exec_vector *Temps; + struct tgsi_exec_vector *Addrs; + + struct tgsi_sampler_state Samplers[16]; + + GLfloat Imms[256][4]; + GLuint ImmLimit; + GLfloat (*Consts)[4]; + const struct tgsi_exec_vector *Inputs; + struct tgsi_exec_vector *Outputs; + struct tgsi_token *Tokens; + GLuint Processor; + + GLuint *Primitives; +#if XXX_SSE + struct x86_function Function; +#endif +}; + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + struct tgsi_token *tokens ); + +void +tgsi_exec_prepare( + struct tgsi_exec_machine *mach, + struct tgsi_exec_labels *labels ); + +void +tgsi_exec_machine_run( + struct tgsi_exec_machine *mach ); + +void +tgsi_exec_machine_run2( + struct tgsi_exec_machine *mach, + struct tgsi_exec_labels *labels ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_EXEC_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_parse.c b/src/mesa/pipe/tgsi/core/tgsi_parse.c new file mode 100644 index 0000000000..df34fa7d7e --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_parse.c @@ -0,0 +1,284 @@ +#include "tgsi_platform.h" +#include "tgsi_core.h" + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ) +{ + full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; +} + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ) +{ + if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) + free( full_token->FullImmediate.u.Pointer ); +} + +GLuint +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ) +{ + ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; + if( ctx->FullVersion.Version.MajorVersion > 1 ) { + return TGSI_PARSE_ERROR; + } + + ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; + if( ctx->FullHeader.Header.HeaderSize >= 2 ) { + ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; + } + else { + ctx->FullHeader.Processor = tgsi_default_processor(); + } + + ctx->Tokens = tokens; + ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; + + tgsi_full_token_init( &ctx->FullToken ); + + return TGSI_PARSE_OK; +} + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ) +{ + tgsi_full_token_free( &ctx->FullToken ); +} + +GLuint +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ) +{ + return ctx->Position >= + 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; +} + +static void +next_token( + struct tgsi_parse_context *ctx, + void *token ) +{ + assert( !tgsi_parse_end_of_tokens( ctx ) ); + + *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; +} + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ) +{ + struct tgsi_token token; + GLuint i; + + tgsi_full_token_free( &ctx->FullToken ); + tgsi_full_token_init( &ctx->FullToken ); + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; + + *decl = tgsi_default_full_declaration(); + decl->Declaration = *(struct tgsi_declaration *) &token; + + switch( decl->Declaration.Type ) { + case TGSI_DECLARE_RANGE: + next_token( ctx, &decl->u.DeclarationRange ); + break; + + case TGSI_DECLARE_MASK: + next_token( ctx, &decl->u.DeclarationMask ); + break; + + default: + assert (0); + } + + if( decl->Declaration.Interpolate ) { + next_token( ctx, &decl->Interpolation ); + } + + break; + } + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; + + *imm = tgsi_default_full_immediate(); + imm->Immediate = *(struct tgsi_immediate *) &token; + + assert( !imm->Immediate.Extended ); + + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + imm->u.Pointer = malloc( + sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + next_token( ctx, &imm->u.ImmediateFloat32[i] ); + } + break; + + default: + assert( 0 ); + } + + break; + } + + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; + GLuint extended; + + *inst = tgsi_default_full_instruction(); + inst->Instruction = *(struct tgsi_instruction *) &token; + + extended = inst->Instruction.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_INSTRUCTION_EXT_TYPE_NV: + inst->InstructionExtNv = + *(struct tgsi_instruction_ext_nv *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_LABEL: + inst->InstructionExtLabel = + *(struct tgsi_instruction_ext_label *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: + inst->InstructionExtTexture = + *(struct tgsi_instruction_ext_texture *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + GLuint extended; + + next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); + assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); + + extended = inst->FullDstRegisters[i].DstRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: + inst->FullDstRegisters[i].DstRegisterExtConcode = + *(struct tgsi_dst_register_ext_concode *) &token; + break; + + case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: + inst->FullDstRegisters[i].DstRegisterExtModulate = + *(struct tgsi_dst_register_ext_modulate *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + } + + assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + GLuint extended; + + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); + + extended = inst->FullSrcRegisters[i].SrcRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: + inst->FullSrcRegisters[i].SrcRegisterExtSwz = + *(struct tgsi_src_register_ext_swz *) &token; + break; + + case TGSI_SRC_REGISTER_EXT_TYPE_MOD: + inst->FullSrcRegisters[i].SrcRegisterExtMod = + *(struct tgsi_src_register_ext_mod *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + + if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); + + /* + * No support for multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); + + if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + } + } + + break; + } + + default: + assert( 0 ); + } +} + diff --git a/src/mesa/pipe/tgsi/core/tgsi_parse.h b/src/mesa/pipe/tgsi/core/tgsi_parse.h new file mode 100644 index 0000000000..61ad0669b1 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_parse.h @@ -0,0 +1,120 @@ +#if !defined TGSI_PARSE_H +#define TGSI_PARSE_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_full_version +{ + struct tgsi_version Version; +}; + +struct tgsi_full_header +{ + struct tgsi_header Header; + struct tgsi_processor Processor; +}; + +struct tgsi_full_dst_register +{ + struct tgsi_dst_register DstRegister; + struct tgsi_dst_register_ext_concode DstRegisterExtConcode; + struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; +}; + +struct tgsi_full_src_register +{ + struct tgsi_src_register SrcRegister; + struct tgsi_src_register_ext_swz SrcRegisterExtSwz; + struct tgsi_src_register_ext_mod SrcRegisterExtMod; + struct tgsi_src_register SrcRegisterInd; + struct tgsi_dimension SrcRegisterDim; + struct tgsi_src_register SrcRegisterDimInd; +}; + +struct tgsi_full_declaration +{ + struct tgsi_declaration Declaration; + union + { + struct tgsi_declaration_range DeclarationRange; + struct tgsi_declaration_mask DeclarationMask; + } u; + struct tgsi_declaration_interpolation Interpolation; +}; + +struct tgsi_full_immediate +{ + struct tgsi_immediate Immediate; + union + { + void *Pointer; + struct tgsi_immediate_float32 *ImmediateFloat32; + } u; +}; + +#define TGSI_FULL_MAX_DST_REGISTERS 2 +#define TGSI_FULL_MAX_SRC_REGISTERS 3 + +struct tgsi_full_instruction +{ + struct tgsi_instruction Instruction; + struct tgsi_instruction_ext_nv InstructionExtNv; + struct tgsi_instruction_ext_label InstructionExtLabel; + struct tgsi_instruction_ext_texture InstructionExtTexture; + struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; + struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; +}; + +union tgsi_full_token +{ + struct tgsi_token Token; + struct tgsi_full_declaration FullDeclaration; + struct tgsi_full_immediate FullImmediate; + struct tgsi_full_instruction FullInstruction; +}; + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ); + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ); + +struct tgsi_parse_context +{ + const struct tgsi_token *Tokens; + GLuint Position; + struct tgsi_full_version FullVersion; + struct tgsi_full_header FullHeader; + union tgsi_full_token FullToken; +}; + +#define TGSI_PARSE_OK 0 +#define TGSI_PARSE_ERROR 1 + +GLuint +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ); + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ); + +GLuint +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ); + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_PARSE_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_token.h b/src/mesa/pipe/tgsi/core/tgsi_token.h new file mode 100644 index 0000000000..becdd480fb --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_token.h @@ -0,0 +1,1045 @@ +#if !defined TGSI_TOKEN_H +#define TGSI_TOKEN_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_version +{ + GLuint MajorVersion : 8; + GLuint MinorVersion : 8; + GLuint Padding : 16; +}; + +struct tgsi_header +{ + GLuint HeaderSize : 8; + GLuint BodySize : 24; +}; + +#define TGSI_PROCESSOR_FRAGMENT 0 +#define TGSI_PROCESSOR_VERTEX 1 +#define TGSI_PROCESSOR_GEOMETRY 2 + +struct tgsi_processor +{ + GLuint Processor : 4; /* TGSI_PROCESSOR_ */ + GLuint Padding : 28; +}; + +#define TGSI_TOKEN_TYPE_DECLARATION 0 +#define TGSI_TOKEN_TYPE_IMMEDIATE 1 +#define TGSI_TOKEN_TYPE_INSTRUCTION 2 + +struct tgsi_token +{ + GLuint Type : 4; /* TGSI_TOKEN_TYPE_ */ + GLuint Size : 8; /* UINT */ + GLuint Padding : 19; + GLuint Extended : 1; /* BOOL */ +}; + +#define TGSI_FILE_NULL 0 +#define TGSI_FILE_CONSTANT 1 +#define TGSI_FILE_INPUT 2 +#define TGSI_FILE_OUTPUT 3 +#define TGSI_FILE_TEMPORARY 4 +#define TGSI_FILE_SAMPLER 5 +#define TGSI_FILE_ADDRESS 6 +#define TGSI_FILE_IMMEDIATE 7 + +#define TGSI_DECLARE_RANGE 0 +#define TGSI_DECLARE_MASK 1 + +struct tgsi_declaration +{ + GLuint Type : 4; /* TGSI_TOKEN_TYPE_DECLARATION */ + GLuint Size : 8; /* UINT */ + GLuint File : 4; /* TGSI_FILE_ */ + GLuint Declare : 4; /* TGSI_DECLARE_ */ + GLuint Interpolate : 1; /* BOOL */ + GLuint Padding : 10; + GLuint Extended : 1; /* BOOL */ +}; + +struct tgsi_declaration_range +{ + GLuint First : 16; /* UINT */ + GLuint Last : 16; /* UINT */ +}; + +struct tgsi_declaration_mask +{ + GLuint Mask : 32; /* UINT */ +}; + +#define TGSI_INTERPOLATE_CONSTANT 0 +#define TGSI_INTERPOLATE_LINEAR 1 +#define TGSI_INTERPOLATE_PERSPECTIVE 2 + +struct tgsi_declaration_interpolation +{ + GLuint Interpolate : 4; /* TGSI_INTERPOLATE_ */ + GLuint Padding : 28; +}; + +#define TGSI_IMM_FLOAT32 0 + +struct tgsi_immediate +{ + GLuint Type : 4; /* TGSI_TOKEN_TYPE_IMMEDIATE */ + GLuint Size : 8; /* UINT */ + GLuint DataType : 4; /* TGSI_IMM_ */ + GLuint Padding : 15; + GLuint Extended : 1; /* BOOL */ +}; + +struct tgsi_immediate_float32 +{ + GLfloat Float; +}; + +/* + * GL_NV_vertex_program + */ +#define TGSI_OPCODE_ARL 0 +#define TGSI_OPCODE_MOV 1 +#define TGSI_OPCODE_LIT 2 +#define TGSI_OPCODE_RCP 3 +#define TGSI_OPCODE_RSQ 4 +#define TGSI_OPCODE_EXP 5 +#define TGSI_OPCODE_LOG 6 +#define TGSI_OPCODE_MUL 7 +#define TGSI_OPCODE_ADD 8 +#define TGSI_OPCODE_DP3 9 +#define TGSI_OPCODE_DP4 10 +#define TGSI_OPCODE_DST 11 +#define TGSI_OPCODE_MIN 12 +#define TGSI_OPCODE_MAX 13 +#define TGSI_OPCODE_SLT 14 +#define TGSI_OPCODE_SGE 15 +#define TGSI_OPCODE_MAD 16 + +/* + * GL_ATI_fragment_shader + */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_MUL */ +#define TGSI_OPCODE_SUB 17 +#define TGSI_OPCODE_DOT3 TGSI_OPCODE_DP3 +#define TGSI_OPCODE_DOT4 TGSI_OPCODE_DP4 +/* TGSI_OPCODE_MAD */ +#define TGSI_OPCODE_LERP 18 +#define TGSI_OPCODE_CND 19 +#define TGSI_OPCODE_CND0 20 +#define TGSI_OPCODE_DOT2ADD 21 + +/* + * GL_EXT_vertex_shader + */ +#define TGSI_OPCODE_INDEX 22 +#define TGSI_OPCODE_NEGATE 23 +/* TGSI_OPCODE_DOT3 */ +/* TGSI_OPCODE_DOT4 */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_ADD */ +#define TGSI_OPCODE_MADD TGSI_OPCODE_MAD +#define TGSI_OPCODE_FRAC 24 +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +#define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE +#define TGSI_OPCODE_SETLT TGSI_OPCODE_SLT +#define TGSI_OPCODE_CLAMP 25 +#define TGSI_OPCODE_FLOOR 26 +#define TGSI_OPCODE_ROUND 27 +#define TGSI_OPCODE_EXPBASE2 28 +#define TGSI_OPCODE_LOGBASE2 29 +#define TGSI_OPCODE_POWER 30 +#define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP +#define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ +/* TGSI_OPCODE_SUB */ +#define TGSI_OPCODE_CROSSPRODUCT 31 +#define TGSI_OPCODE_MULTIPLYMATRIX 32 +/* TGSI_OPCODE_MOV */ + +/* + * GL_NV_vertex_program1_1 + */ +/* TGSI_OPCODE_ARL */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_LIT */ +#define TGSI_OPCODE_ABS 33 +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_EXP */ +/* TGSI_OPCODE_LOG */ +#define TGSI_OPCODE_RCC 34 +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SGE */ +#define TGSI_OPCODE_DPH 35 +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_MAD */ + +/* + * GL_NV_fragment_program + */ +/* TGSI_OPCODE_ADD */ +#define TGSI_OPCODE_COS 36 +#define TGSI_OPCODE_DDX 37 +#define TGSI_OPCODE_DDY 38 +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DST */ +#define TGSI_OPCODE_EX2 TGSI_OPCODE_EXPBASE2 +#define TGSI_OPCODE_FLR TGSI_OPCODE_FLOOR +#define TGSI_OPCODE_FRC TGSI_OPCODE_FRAC +#define TGSI_OPCODE_KIL 39 +#define TGSI_OPCODE_LG2 TGSI_OPCODE_LOGBASE2 +/* TGSI_OPCODE_LIT */ +#define TGSI_OPCODE_LRP TGSI_OPCODE_LERP +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_MUL */ +#define TGSI_OPCODE_PK2H 40 +#define TGSI_OPCODE_PK2US 41 +#define TGSI_OPCODE_PK4B 42 +#define TGSI_OPCODE_PK4UB 43 +#define TGSI_OPCODE_POW TGSI_OPCODE_POWER +/* TGSI_OPCODE_RCP */ +#define TGSI_OPCODE_RFL 44 +/* TGSI_OPCODE_RSQ */ +#define TGSI_OPCODE_SEQ 45 +#define TGSI_OPCODE_SFL 46 +/* TGSI_OPCODE_SGE */ +#define TGSI_OPCODE_SGT 47 +#define TGSI_OPCODE_SIN 48 +#define TGSI_OPCODE_SLE 49 +/* TGSI_OPCODE_SLT */ +#define TGSI_OPCODE_SNE 50 +#define TGSI_OPCODE_STR 51 +/* TGSI_OPCODE_SUB */ +#define TGSI_OPCODE_TEX 52 +#define TGSI_OPCODE_TXD 53 +/* TGSI_OPCODE_TXP - use TGSI_OPCODE_TEX */ +#define TGSI_OPCODE_UP2H 54 +#define TGSI_OPCODE_UP2US 55 +#define TGSI_OPCODE_UP4B 56 +#define TGSI_OPCODE_UP4UB 57 +#define TGSI_OPCODE_X2D 58 + +/* + * GL_NV_vertex_program2 + */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_ADD */ +#define TGSI_OPCODE_ARA 59 +/* TGSI_OPCODE_ARL */ +#define TGSI_OPCODE_ARR 60 +#define TGSI_OPCODE_BRA 61 +#define TGSI_OPCODE_CAL 62 +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_EXP */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_LOG */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_RCC */ +/* TGSI_OPCODE_RCP */ +#define TGSI_OPCODE_RET 63 +/* TGSI_OPCODE_RSQNV */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SNE */ +#define TGSI_OPCODE_SSG 64 +/* TGSI_OPCODE_STR */ +/* TGSI_OPCODE_SUB */ + +/* + * GL_ARB_vertex_program + */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_ARL */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_EXP */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_LOG */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +#define TGSI_OPCODE_SWZ TGSI_OPCODE_MOV +#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT + +/* + * GL_ARB_fragment_program + */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_ADD */ +#define TGSI_OPCODE_CMP 65 +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_LRP */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +#define TGSI_OPCODE_SCS 66 +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_TEX */ +/* TGSI_OPCODE_TXP */ +#define TGSI_OPCODE_TXB 67 +/* TGSI_OPCODE_KIL */ + +/* + * GL_NV_fragment_program_option + */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_DDX */ +/* TGSI_OPCODE_DDY */ +/* TGSI_OPCODE_PK2H */ +/* TGSI_OPCODE_PK2US */ +/* TGSI_OPCODE_PK4B */ +/* TGSI_OPCODE_PK4UB */ +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_SCS */ +/* TGSI_OPCODE_UP2H */ +/* TGSI_OPCODE_UP2US */ +/* TGSI_OPCODE_UP4B */ +/* TGSI_OPCODE_UP4UB */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_RFL */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SNE */ +/* TGSI_OPCODE_STR */ +/* TGSI_OPCODE_CMP */ +/* TGSI_OPCODE_LRP */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_X2D */ +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_TEX */ +/* TGSI_OPCODE_TXP */ +/* TGSI_OPCODE_TXB */ +/* TGSI_OPCODE_KIL */ +/* TGSI_OPCODE_TXD */ + +/* + * GL_NV_fragment_program2 + */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_DDX */ +/* TGSI_OPCODE_DDY */ +/* TGSI_OPCODE_PK2H */ +/* TGSI_OPCODE_PK2US */ +/* TGSI_OPCODE_PK4B */ +/* TGSI_OPCODE_PK4UB */ +#define TGSI_OPCODE_NRM 68 +#define TGSI_OPCODE_DIV 69 +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_SCS */ +/* TGSI_OPCODE_UP2H */ +/* TGSI_OPCODE_UP2US */ +/* TGSI_OPCODE_UP4B */ +/* TGSI_OPCODE_UP4UB */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_RFL */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SNE */ +/* TGSI_OPCODE_STR */ +#define TGSI_OPCODE_DP2 70 +/* TGSI_OPCODE_CMP */ +/* TGSI_OPCODE_LRP */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_X2D */ +#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_TEX */ +/* TGSI_OPCODE_TXP */ +/* TGSI_OPCODE_TXB */ +#define TGSI_OPCODE_TXL 71 +/* TGSI_OPCODE_KIL */ +/* TGSI_OPCODE_TXD */ +/* TGSI_OPCODE_CAL */ +/* TGSI_OPCODE_RET */ +#define TGSI_OPCODE_BRK 72 +#define TGSI_OPCODE_IF 73 +#define TGSI_OPCODE_LOOP 74 +#define TGSI_OPCODE_REP 75 +#define TGSI_OPCODE_ELSE 76 +#define TGSI_OPCODE_ENDIF 77 +#define TGSI_OPCODE_ENDLOOP 78 +#define TGSI_OPCODE_ENDREP 79 + +/* + * GL_NV_vertex_program2_option + */ +/* TGSI_OPCODE_ARL */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_SSG */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_EXP */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_LOG */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_RCC */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SNE */ +/* TGSI_OPCODE_STR */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_ARR */ +/* TGSI_OPCODE_ARA */ +/* TGSI_OPCODE_BRA */ +/* TGSI_OPCODE_CAL */ +/* TGSI_OPCODE_RET */ + +/* + * GL_NV_vertex_program3 + */ +/* TGSI_OPCODE_ARL */ +/* TGSI_OPCODE_ABS */ +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_MOV */ +/* TGSI_OPCODE_SSG */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_EXP */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_LOG */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_RCC */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_ADD */ +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MUL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SNE */ +/* TGSI_OPCODE_STR */ +/* TGSI_OPCODE_MAD */ +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_ARR */ +/* TGSI_OPCODE_ARA */ +/* TGSI_OPCODE_BRA */ +/* TGSI_OPCODE_CAL */ +/* TGSI_OPCODE_RET */ +#define TGSI_OPCODE_PUSHA 80 +#define TGSI_OPCODE_POPA 81 +/* TGSI_OPCODE_TEX */ +/* TGSI_OPCODE_TXP */ +/* TGSI_OPCODE_TXB */ +/* TGSI_OPCODE_TXL */ + +/* + * GL_NV_gpu_program4 + */ +/* TGSI_OPCODE_ABS */ +#define TGSI_OPCODE_CEIL 82 +/* TGSI_OPCODE_FLR */ +/* TGSI_OPCODE_FRC */ +#define TGSI_OPCODE_I2F 83 +/* TGSI_OPCODE_LIT */ +/* TGSI_OPCODE_MOV */ +#define TGSI_OPCODE_NOT 84 +/* TGSI_OPCODE_NRM */ +/* TGSI_OPCODE_PK2H */ +/* TGSI_OPCODE_PK2US */ +/* TGSI_OPCODE_PK4B */ +/* TGSI_OPCODE_PK4UB */ +/* TGSI_OPCODE_ROUND */ +/* TGSI_OPCODE_SSG */ +#define TGSI_OPCODE_TRUNC 85 +/* TGSI_OPCODE_COS */ +/* TGSI_OPCODE_EX2 */ +/* TGSI_OPCODE_LG2 */ +/* TGSI_OPCODE_RCC */ +/* TGSI_OPCODE_RCP */ +/* TGSI_OPCODE_RSQ */ +/* TGSI_OPCODE_SCS */ +/* TGSI_OPCODE_SIN */ +/* TGSI_OPCODE_UP2H */ +/* TGSI_OPCODE_UP2US */ +/* TGSI_OPCODE_UP4B */ +/* TGSI_OPCODE_UP4UB */ +/* TGSI_OPCODE_POW */ +/* TGSI_OPCODE_DIV */ +#define TGSI_OPCODE_SHL 86 +#define TGSI_OPCODE_SHR 87 +/* TGSI_OPCODE_ADD */ +#define TGSI_OPCODE_AND 88 +/* TGSI_OPCODE_DP3 */ +/* TGSI_OPCODE_DP4 */ +/* TGSI_OPCODE_DPH */ +/* TGSI_OPCODE_DST */ +/* TGSI_OPCODE_MAX */ +/* TGSI_OPCODE_MIN */ +/* TGSI_OPCODE_MUL */ +#define TGSI_OPCODE_OR 89 +/* TGSI_OPCODE_RFL */ +/* TGSI_OPCODE_SEQ */ +/* TGSI_OPCODE_SFL */ +/* TGSI_OPCODE_SGE */ +/* TGSI_OPCODE_SGT */ +/* TGSI_OPCODE_SLE */ +/* TGSI_OPCODE_SLT */ +/* TGSI_OPCODE_SNE */ +/* TGSI_OPCODE_STR */ +/* TGSI_OPCODE_SUB */ +/* TGSI_OPCODE_XPD */ +/* TGSI_OPCODE_DP2 */ +#define TGSI_OPCODE_MOD 90 +#define TGSI_OPCODE_XOR 91 +/* TGSI_OPCODE_CMP */ +/* TGSI_OPCODE_DP2A */ +/* TGSI_OPCODE_LRP */ +/* TGSI_OPCODE_MAD */ +#define TGSI_OPCODE_SAD 92 +/* TGSI_OPCODE_X2D */ +/* TGSI_OPCODE_SWZ */ +/* TGSI_OPCODE_TEX */ +/* TGSI_OPCODE_TXB */ +#define TGSI_OPCODE_TXF 93 +/* TGSI_OPCODE_TXL */ +/* TGSI_OPCODE_TXP */ +#define TGSI_OPCODE_TXQ 94 +/* TGSI_OPCODE_TXD */ +/* TGSI_OPCODE_CAL */ +/* TGSI_OPCODE_RET */ +/* TGSI_OPCODE_BRK */ +#define TGSI_OPCODE_CONT 95 +/* TGSI_OPCODE_IF */ +/* TGSI_OPCODE_REP */ +/* TGSI_OPCODE_ELSE */ +/* TGSI_OPCODE_ENDIF */ +/* TGSI_OPCODE_ENDREP */ + +/* + * GL_NV_vertex_program4 + */ +/* Same as GL_NV_gpu_program4 */ + +/* + * GL_NV_fragment_program4 + */ +/* Same as GL_NV_gpu_program4 */ +/* TGSI_OPCODE_KIL */ +/* TGSI_OPCODE_DDX */ +/* TGSI_OPCODE_DDY */ + +/* + * GL_NV_geometry_program4 + */ +/* Same as GL_NV_gpu_program4 */ +#define TGSI_OPCODE_EMIT 96 +#define TGSI_OPCODE_ENDPRIM 97 + +#define TGSI_OPCODE_LAST 98 + +#define TGSI_SAT_NONE 0 /* do not saturate */ +#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ +#define TGSI_SAT_MINUS_PLUS_ONE 2 /* clamp to [-1,1] */ + +/* + * Opcode is the operation code to execute. A given operation defines the + * semantics how the source registers (if any) are interpreted and what is + * written to the destination registers (if any) as a result of execution. + * + * NumDstRegs and NumSrcRegs is the number of destination and source registers, + * respectively. For a given operation code, those numbers are fixed and are + * present here only for convenience. + * + * If Extended is TRUE, it is now executed. + * + * Saturate controls how are final results in destination registers modified. + */ + +struct tgsi_instruction +{ + GLuint Type : 4; /* TGSI_TOKEN_TYPE_INSTRUCTION */ + GLuint Size : 8; /* UINT */ + GLuint Opcode : 8; /* TGSI_OPCODE_ */ + GLuint Saturate : 2; /* TGSI_SAT_ */ + GLuint NumDstRegs : 2; /* UINT */ + GLuint NumSrcRegs : 4; /* UINT */ + GLuint Padding : 3; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_instruction::Extended is TRUE, tgsi_instruction_ext follows. + * + * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow. + * + * Then, tgsi_instruction::NumSrcRegs of tgsi_src_register follow. + * + * tgsi_instruction::Size contains the total number of words that make the + * instruction, including the instruction word. + */ + +#define TGSI_INSTRUCTION_EXT_TYPE_NV 0 +#define TGSI_INSTRUCTION_EXT_TYPE_LABEL 1 +#define TGSI_INSTRUCTION_EXT_TYPE_TEXTURE 2 + +struct tgsi_instruction_ext +{ + GLuint Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_ */ + GLuint Padding : 27; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_NV, it should + * be cast to tgsi_instruction_ext_nv. + * + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_LABEL, it + * should be cast to tgsi_instruction_ext_label. + * + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_TEXTURE, it + * should be cast to tgsi_instruction_ext_texture. + * + * If tgsi_instruction_ext::Extended is TRUE, another tgsi_instruction_ext + * follows. + */ + +#define TGSI_PRECISION_DEFAULT 0 +#define TGSI_PRECISION_FLOAT32 1 +#define TGSI_PRECISION_FLOAT16 2 +#define TGSI_PRECISION_FIXED12 3 + +#define TGSI_CC_GT 0 +#define TGSI_CC_EQ 1 +#define TGSI_CC_LT 2 +#define TGSI_CC_UN 3 +#define TGSI_CC_GE 4 +#define TGSI_CC_LE 5 +#define TGSI_CC_NE 6 +#define TGSI_CC_TR 7 +#define TGSI_CC_FL 8 + +#define TGSI_SWIZZLE_X 0 +#define TGSI_SWIZZLE_Y 1 +#define TGSI_SWIZZLE_Z 2 +#define TGSI_SWIZZLE_W 3 + +/* + * Precision controls the precision at which the operation should be executed. + * + * CondDstUpdate enables condition code register writes. When this field is + * TRUE, CondDstIndex specifies the index of the condition code register to + * update. + * + * CondFlowEnable enables conditional execution of the operation. When this + * field is TRUE, CondFlowIndex specifies the index of the condition code + * register to test against CondMask with component swizzle controled by + * CondSwizzleX, CondSwizzleY, CondSwizzleZ and CondSwizzleW. If the test fails, + * the operation is not executed. + */ + +struct tgsi_instruction_ext_nv +{ + GLuint Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_NV */ + GLuint Precision : 4; /* TGSI_PRECISION_ */ + GLuint CondDstIndex : 4; /* UINT */ + GLuint CondFlowIndex : 4; /* UINT */ + GLuint CondMask : 4; /* TGSI_CC_ */ + GLuint CondSwizzleX : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleY : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleW : 2; /* TGSI_SWIZZLE_ */ + GLuint CondDstUpdate : 1; /* BOOL */ + GLuint CondFlowEnable : 1; /* BOOL */ + GLuint Padding : 1; + GLuint Extended : 1; /* BOOL */ +}; + +struct tgsi_instruction_ext_label +{ + GLuint Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_LABEL */ + GLuint Label : 24; /* UINT */ + GLuint Target : 1; /* BOOL */ + GLuint Padding : 2; + GLuint Extended : 1; /* BOOL */ +}; + +#define TGSI_TEXTURE_UNKNOWN 0 +#define TGSI_TEXTURE_1D 1 +#define TGSI_TEXTURE_2D 2 +#define TGSI_TEXTURE_3D 3 +#define TGSI_TEXTURE_CUBE 4 +#define TGSI_TEXTURE_RECT 5 +#define TGSI_TEXTURE_SHADOW1D 6 +#define TGSI_TEXTURE_SHADOW2D 7 +#define TGSI_TEXTURE_SHADOWRECT 8 + +struct tgsi_instruction_ext_texture +{ + GLuint Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_TEXTURE */ + GLuint Texture : 8; /* TGSI_TEXTURE_ */ + GLuint Padding : 19; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * File specifies the register array to access. + * + * Index specifies the element number of a register in the register file. + * + * If Indirect is TRUE, Index should be offset by the X component of a source + * register that follows. The register can be now fetched into local storage + * for further processing. + * + * If Negate is TRUE, all components of the fetched register are negated. + * + * The fetched register components are swizzled according to SwizzleX, SwizzleY, + * SwizzleZ and SwizzleW. + * + * If Extended is TRUE, any further modifications to the source register are + * made to this temporary storage. + */ + +struct tgsi_src_register +{ + GLuint File : 4; /* TGSI_FILE_ */ + GLuint SwizzleX : 2; /* TGSI_SWIZZLE_ */ + GLuint SwizzleY : 2; /* TGSI_SWIZZLE_ */ + GLuint SwizzleZ : 2; /* TGSI_SWIZZLE_ */ + GLuint SwizzleW : 2; /* TGSI_SWIZZLE_ */ + GLuint Negate : 1; /* BOOL */ + GLuint Indirect : 1; /* BOOL */ + GLuint Dimension : 1; /* BOOL */ + GLint Index : 16; /* SINT */ + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_src_register::Extended is TRUE, tgsi_src_register_ext follows. + * + * Then, if tgsi_src_register::Indirect is TRUE, another tgsi_src_register + * follows. + * + * Then, if tgsi_src_register::Dimension is TRUE, tgsi_dimension follows. + */ + +#define TGSI_SRC_REGISTER_EXT_TYPE_SWZ 0 +#define TGSI_SRC_REGISTER_EXT_TYPE_MOD 1 + +struct tgsi_src_register_ext +{ + GLuint Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_ */ + GLuint Padding : 27; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_SWZ, + * it should be cast to tgsi_src_register_ext_extswz. + * + * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_MOD, + * it should be cast to tgsi_src_register_ext_mod. + * + * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext + * follows. + */ + +#define TGSI_EXTSWIZZLE_X TGSI_SWIZZLE_X +#define TGSI_EXTSWIZZLE_Y TGSI_SWIZZLE_Y +#define TGSI_EXTSWIZZLE_Z TGSI_SWIZZLE_Z +#define TGSI_EXTSWIZZLE_W TGSI_SWIZZLE_W +#define TGSI_EXTSWIZZLE_ZERO 4 +#define TGSI_EXTSWIZZLE_ONE 5 + +/* + * ExtSwizzleX, ExtSwizzleY, ExtSwizzleZ and ExtSwizzleW swizzle the source + * register in an extended manner. + * + * NegateX, NegateY, NegateZ and NegateW negate individual components of the + * source register. + * + * ExtDivide specifies which component is used to divide all components of the + * source register. + */ + +struct tgsi_src_register_ext_swz +{ + GLuint Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_SWZ */ + GLuint ExtSwizzleX : 4; /* TGSI_EXTSWIZZLE_ */ + GLuint ExtSwizzleY : 4; /* TGSI_EXTSWIZZLE_ */ + GLuint ExtSwizzleZ : 4; /* TGSI_EXTSWIZZLE_ */ + GLuint ExtSwizzleW : 4; /* TGSI_EXTSWIZZLE_ */ + GLuint NegateX : 1; /* BOOL */ + GLuint NegateY : 1; /* BOOL */ + GLuint NegateZ : 1; /* BOOL */ + GLuint NegateW : 1; /* BOOL */ + GLuint ExtDivide : 4; /* TGSI_EXTSWIZZLE_ */ + GLuint Padding : 3; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If Complement is TRUE, the source register is modified by subtracting it + * from 1.0. + * + * If Bias is TRUE, the source register is modified by subtracting 0.5 from it. + * + * If Scale2X is TRUE, the source register is modified by multiplying it by 2.0. + * + * If Absolute is TRUE, the source register is modified by removing the sign. + * + * If Negate is TRUE, the source register is modified by negating it. + */ + +struct tgsi_src_register_ext_mod +{ + GLuint Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_MOD */ + GLuint Complement : 1; /* BOOL */ + GLuint Bias : 1; /* BOOL */ + GLuint Scale2X : 1; /* BOOL */ + GLuint Absolute : 1; /* BOOL */ + GLuint Negate : 1; /* BOOL */ + GLuint Padding : 22; + GLuint Extended : 1; /* BOOL */ +}; + +struct tgsi_dimension +{ + GLuint Indirect : 1; /* BOOL */ + GLuint Dimension : 1; /* BOOL */ + GLuint Padding : 13; + GLint Index : 16; /* SINT */ + GLuint Extended : 1; /* BOOL */ +}; + +#define TGSI_WRITEMASK_NONE 0x00 +#define TGSI_WRITEMASK_X 0x01 +#define TGSI_WRITEMASK_Y 0x02 +#define TGSI_WRITEMASK_XY 0x03 +#define TGSI_WRITEMASK_Z 0x04 +#define TGSI_WRITEMASK_XZ 0x05 +#define TGSI_WRITEMASK_YZ 0x06 +#define TGSI_WRITEMASK_XYZ 0x07 +#define TGSI_WRITEMASK_W 0x08 +#define TGSI_WRITEMASK_XW 0x09 +#define TGSI_WRITEMASK_YW 0x0A +#define TGSI_WRITEMASK_XYW 0x0B +#define TGSI_WRITEMASK_ZW 0x0C +#define TGSI_WRITEMASK_XZW 0x0D +#define TGSI_WRITEMASK_YZW 0x0E +#define TGSI_WRITEMASK_XYZW 0x0F + +struct tgsi_dst_register +{ + GLuint File : 4; /* TGSI_FILE_ */ + GLuint WriteMask : 4; /* TGSI_WRITEMASK_ */ + GLuint Indirect : 1; /* BOOL */ + GLuint Dimension : 1; /* BOOL */ + GLint Index : 16; /* SINT */ + GLuint Padding : 5; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_dst_register::Extended is TRUE, tgsi_dst_register_ext follows. + * + * Then, if tgsi_dst_register::Indirect is TRUE, tgsi_src_register follows. + */ + +#define TGSI_DST_REGISTER_EXT_TYPE_CONDCODE 0 +#define TGSI_DST_REGISTER_EXT_TYPE_MODULATE 1 + +struct tgsi_dst_register_ext +{ + GLuint Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_ */ + GLuint Padding : 27; + GLuint Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_CONDCODE, + * it should be cast to tgsi_dst_register_ext_condcode. + * + * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_MODULATE, + * it should be cast to tgsi_dst_register_ext_modulate. + * + * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext + * follows. + */ + +struct tgsi_dst_register_ext_concode +{ + GLuint Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_CONDCODE */ + GLuint CondMask : 4; /* TGSI_CC_ */ + GLuint CondSwizzleX : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleY : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSwizzleW : 2; /* TGSI_SWIZZLE_ */ + GLuint CondSrcIndex : 4; /* UINT */ + GLuint Padding : 11; + GLuint Extended : 1; /* BOOL */ +}; + +#define TGSI_MODULATE_1X 0 +#define TGSI_MODULATE_2X 1 +#define TGSI_MODULATE_4X 2 +#define TGSI_MODULATE_8X 3 +#define TGSI_MODULATE_HALF 4 +#define TGSI_MODULATE_QUARTER 5 +#define TGSI_MODULATE_EIGHTH 6 + +struct tgsi_dst_register_ext_modulate +{ + GLuint Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_MODULATE */ + GLuint Modulate : 4; /* TGSI_MODULATE_ */ + GLuint Padding : 23; + GLuint Extended : 1; /* BOOL */ +}; + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_TOKEN_H + diff --git a/src/mesa/pipe/tgsi/core/tgsi_util.c b/src/mesa/pipe/tgsi/core/tgsi_util.c new file mode 100644 index 0000000000..2331affdfd --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_util.c @@ -0,0 +1,263 @@ +#include "tgsi_platform.h" +#include "tgsi_core.h" + +void * +tgsi_align_128bit( + void *unaligned ) +{ + GLuint *ptr, addr; + + ptr = (GLuint *) unaligned; + addr = (*(GLuint *) &ptr + 15) & ~15; + return *(void **) &addr; +} + +GLuint +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + GLuint component ) +{ + switch( component ) { + case 0: + return reg->SwizzleX; + case 1: + return reg->SwizzleY; + case 2: + return reg->SwizzleZ; + case 3: + return reg->SwizzleW; + default: + assert( 0 ); + } + return 0; +} + +GLuint +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + GLuint component ) +{ + switch( component ) { + case 0: + return reg->ExtSwizzleX; + case 1: + return reg->ExtSwizzleY; + case 2: + return reg->ExtSwizzleZ; + case 3: + return reg->ExtSwizzleW; + default: + assert( 0 ); + } + return 0; +} + +GLuint +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + GLuint component ) +{ + GLuint swizzle; + + /* + * First, calculate the extended swizzle for a given channel. This will give + * us either a channel index into the simple swizzle or a constant 1 or 0. + */ + swizzle = tgsi_util_get_src_register_extswizzle( + ®->SrcRegisterExtSwz, + component ); + + assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); + assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); + assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); + assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); + + /* + * Second, calculate the simple swizzle for the unswizzled channel index. + * Leave the constants intact, they are not affected by the simple swizzle. + */ + if( swizzle <= TGSI_SWIZZLE_W ) { + swizzle = tgsi_util_get_src_register_swizzle( + ®->SrcRegister, + swizzle ); + } + + return swizzle; +} + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + GLuint swizzle, + GLuint component ) +{ + switch( component ) { + case 0: + reg->SwizzleX = swizzle; + break; + case 1: + reg->SwizzleY = swizzle; + break; + case 2: + reg->SwizzleZ = swizzle; + break; + case 3: + reg->SwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + GLuint swizzle, + GLuint component ) +{ + switch( component ) { + case 0: + reg->ExtSwizzleX = swizzle; + break; + case 1: + reg->ExtSwizzleY = swizzle; + break; + case 2: + reg->ExtSwizzleZ = swizzle; + break; + case 3: + reg->ExtSwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +GLuint +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + GLuint component ) +{ + switch( component ) { + case 0: + return reg->NegateX; + case 1: + return reg->NegateY; + case 2: + return reg->NegateZ; + case 3: + return reg->NegateW; + default: + assert( 0 ); + } + return 0; +} + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + GLuint negate, + GLuint component ) +{ + switch( component ) { + case 0: + reg->NegateX = negate; + break; + case 1: + reg->NegateY = negate; + break; + case 2: + reg->NegateZ = negate; + break; + case 3: + reg->NegateW = negate; + break; + default: + assert( 0 ); + } +} + +GLuint +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + GLuint component ) +{ + GLuint sign_mode; + + if( reg->SrcRegisterExtMod.Absolute ) { + /* Consider only the post-abs negation. */ + + if( reg->SrcRegisterExtMod.Negate ) { + sign_mode = TGSI_UTIL_SIGN_SET; + } + else { + sign_mode = TGSI_UTIL_SIGN_CLEAR; + } + } + else { + /* Accumulate the three negations. */ + + GLuint negate; + + negate = reg->SrcRegister.Negate; + if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { + negate = !negate; + } + if( reg->SrcRegisterExtMod.Negate ) { + negate = !negate; + } + + if( negate ) { + sign_mode = TGSI_UTIL_SIGN_TOGGLE; + } + else { + sign_mode = TGSI_UTIL_SIGN_KEEP; + } + } + + return sign_mode; +} + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + GLuint sign_mode ) +{ + reg->SrcRegisterExtSwz.NegateX = 0; + reg->SrcRegisterExtSwz.NegateY = 0; + reg->SrcRegisterExtSwz.NegateZ = 0; + reg->SrcRegisterExtSwz.NegateW = 0; + + switch (sign_mode) + { + case TGSI_UTIL_SIGN_CLEAR: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_SET: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 1; + break; + + case TGSI_UTIL_SIGN_TOGGLE: + reg->SrcRegister.Negate = 1; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_KEEP: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + default: + assert( 0 ); + } +} + diff --git a/src/mesa/pipe/tgsi/core/tgsi_util.h b/src/mesa/pipe/tgsi/core/tgsi_util.h new file mode 100644 index 0000000000..70c48690c5 --- /dev/null +++ b/src/mesa/pipe/tgsi/core/tgsi_util.h @@ -0,0 +1,70 @@ +#if !defined TGSI_UTIL_H +#define TGSI_UTIL_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +void * +tgsi_align_128bit( + void *unaligned ); + +GLuint +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + GLuint component ); + +GLuint +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + GLuint component); + +GLuint +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + GLuint component ); + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + GLuint swizzle, + GLuint component ); + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + GLuint swizzle, + GLuint component ); + +GLuint +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + GLuint component ); + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + GLuint negate, + GLuint component ); + +#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ +#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ +#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ +#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ + +GLuint +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + GLuint component ); + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + GLuint sign_mode ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_UTIL_H + diff --git a/src/mesa/pipe/tgsi/mesa/Makefile b/src/mesa/pipe/tgsi/mesa/Makefile new file mode 100644 index 0000000000..eb8b14e0e8 --- /dev/null +++ b/src/mesa/pipe/tgsi/mesa/Makefile @@ -0,0 +1,3 @@ +default: + cd ../../.. ; make + diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c new file mode 100644 index 0000000000..e37778fe41 --- /dev/null +++ b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c @@ -0,0 +1,499 @@ +#include "tgsi_platform.h"
+#include "tgsi_mesa.h"
+
+/*
+ * Map mesa register file to SBIR register file.
+ */
+static GLuint
+map_register_file( enum register_file file )
+{
+ switch (file) {
+ case PROGRAM_UNDEFINED:
+ return TGSI_FILE_NULL;
+ case PROGRAM_TEMPORARY:
+ return TGSI_FILE_TEMPORARY;
+ //case PROGRAM_LOCAL_PARAM:
+ //case PROGRAM_ENV_PARAM:
+ case PROGRAM_STATE_VAR:
+ //case PROGRAM_NAMED_PARAM:
+ case PROGRAM_CONSTANT:
+ return TGSI_FILE_CONSTANT;
+ case PROGRAM_INPUT:
+ return TGSI_FILE_INPUT;
+ case PROGRAM_OUTPUT:
+ return TGSI_FILE_OUTPUT;
+ case PROGRAM_ADDRESS:
+ return TGSI_FILE_ADDRESS;
+ default:
+ assert (0);
+ return TGSI_FILE_NULL;
+ }
+}
+
+/*
+ * Map mesa register file index to SBIR index.
+ * Take special care when processing input and output indices.
+ */
+static GLuint
+map_register_file_index( GLuint processor,
+ GLuint file,
+ GLuint index,
+ GLuint usage_bitmask )
+{
+ GLuint mapped_index;
+ GLuint i;
+
+ switch (file)
+ {
+ case TGSI_FILE_INPUT:
+ assert (index < 32);
+ assert (usage_bitmask & (1 << index));
+ mapped_index = 0;
+ for (i = 0; i < index; i++) {
+ if (usage_bitmask & (1 << i))
+ mapped_index++;
+ }
+ break;
+
+ case TGSI_FILE_OUTPUT:
+ assert (usage_bitmask == 0);
+ if (processor == TGSI_PROCESSOR_FRAGMENT) {
+ if (index == FRAG_RESULT_DEPR) {
+ mapped_index = 0;
+ } else {
+ assert (index == FRAG_RESULT_COLR);
+ mapped_index = index + 1;
+ }
+ } else {
+ mapped_index = index;
+ }
+ break;
+
+ default:
+ mapped_index = index;
+ }
+
+ return mapped_index;
+}
+
+/*
+ * Map mesa texture target to SBIR texture target.
+ */
+static GLuint
+map_texture_target( GLuint textarget )
+{
+ switch (textarget) {
+ case TEXTURE_1D_INDEX:
+ return TGSI_TEXTURE_1D;
+ case TEXTURE_2D_INDEX:
+ return TGSI_TEXTURE_2D;
+ case TEXTURE_3D_INDEX:
+ return TGSI_TEXTURE_3D;
+ case TEXTURE_CUBE_INDEX:
+ return TGSI_TEXTURE_CUBE;
+ case TEXTURE_RECT_INDEX:
+ return TGSI_TEXTURE_RECT;
+ default:
+ assert (0);
+ }
+ return TGSI_TEXTURE_1D;
+}
+
+static GLuint
+convert_sat( GLuint sat )
+{
+ switch (sat) {
+ case SATURATE_OFF:
+ return TGSI_SAT_NONE;
+ case SATURATE_ZERO_ONE:
+ return TGSI_SAT_ZERO_ONE;
+ case SATURATE_PLUS_MINUS_ONE:
+ return TGSI_SAT_MINUS_PLUS_ONE;
+ default:
+ assert (0);
+ return TGSI_SAT_NONE;
+ }
+}
+
+static GLuint
+convert_writemask( GLuint writemask )
+{
+ assert (WRITEMASK_X == TGSI_WRITEMASK_X);
+ assert (WRITEMASK_Y == TGSI_WRITEMASK_Y);
+ assert (WRITEMASK_Z == TGSI_WRITEMASK_Z);
+ assert (WRITEMASK_W == TGSI_WRITEMASK_W);
+ assert ((writemask & ~TGSI_WRITEMASK_XYZW) == 0);
+
+ return writemask;
+}
+
+static GLboolean
+compile_instruction( struct prog_instruction *inst,
+ struct tgsi_full_instruction *fullinst,
+ GLuint inputs_read,
+ GLuint processor )
+{
+ GLuint i;
+ struct tgsi_full_dst_register *fulldst;
+ struct tgsi_full_src_register *fullsrc;
+
+ *fullinst = tgsi_default_full_instruction ();
+
+ fullinst->Instruction.Saturate = convert_sat (inst->SaturateMode);
+ fullinst->Instruction.NumDstRegs = 1;
+ fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs (inst->Opcode);
+
+ fulldst = &fullinst->FullDstRegisters[0];
+ fulldst->DstRegister.File =
+ map_register_file (inst->DstReg.File);
+ fulldst->DstRegister.Index =
+ map_register_file_index (processor,
+ fulldst->DstRegister.File,
+ inst->DstReg.Index,
+ 0);
+ fulldst->DstRegister.WriteMask =
+ convert_writemask (inst->DstReg.WriteMask);
+
+ for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
+ GLuint j;
+
+ fullsrc = &fullinst->FullSrcRegisters[i];
+ fullsrc->SrcRegister.File =
+ map_register_file (inst->SrcReg[i].File);
+ fullsrc->SrcRegister.Index =
+ map_register_file_index (processor,
+ fullsrc->SrcRegister.File,
+ inst->SrcReg[i].Index,
+ inputs_read);
+
+ for (j = 0; j < 4; j++) {
+ GLuint swz;
+
+ swz = GET_SWZ(inst->SrcReg[i].Swizzle, j);
+ if (swz > SWIZZLE_W) {
+ tgsi_util_set_src_register_extswizzle (
+ &fullsrc->SrcRegisterExtSwz,
+ swz,
+ j);
+ } else {
+ tgsi_util_set_src_register_swizzle (
+ &fullsrc->SrcRegister,
+ swz,
+ j);
+ }
+ }
+
+ if (inst->SrcReg[i].NegateBase == NEGATE_XYZW) {
+ fullsrc->SrcRegister.Negate = 1;
+ } else if (inst->SrcReg[i].NegateBase != NEGATE_NONE) {
+ if (inst->SrcReg[i].NegateBase & NEGATE_X)
+ fullsrc->SrcRegisterExtSwz.NegateX = 1;
+ if (inst->SrcReg[i].NegateBase & NEGATE_Y)
+ fullsrc->SrcRegisterExtSwz.NegateY = 1;
+ if (inst->SrcReg[i].NegateBase & NEGATE_Z)
+ fullsrc->SrcRegisterExtSwz.NegateZ = 1;
+ if (inst->SrcReg[i].NegateBase & NEGATE_W)
+ fullsrc->SrcRegisterExtSwz.NegateW = 1;
+ }
+
+ if (inst->SrcReg[i].Abs)
+ fullsrc->SrcRegisterExtMod.Absolute = 1;
+
+ if (inst->SrcReg[i].NegateAbs)
+ fullsrc->SrcRegisterExtMod.Negate = 1;
+
+ if (inst->SrcReg[i].RelAddr) {
+ fullsrc->SrcRegister.Indirect = 1;
+
+ fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
+ fullsrc->SrcRegisterInd.Index = 0;
+ }
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_ARL:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
+ break;
+ case OPCODE_ABS:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
+ break;
+ case OPCODE_ADD:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
+ break;
+ case OPCODE_CMP:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
+ break;
+ case OPCODE_COS:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
+ break;
+ case OPCODE_DP3:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
+ break;
+ case OPCODE_DP4:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
+ break;
+ case OPCODE_DPH:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
+ break;
+ case OPCODE_DST:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
+ break;
+ case OPCODE_EX2:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
+ break;
+ case OPCODE_FLR:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
+ break;
+ case OPCODE_FRC:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
+ break;
+ case OPCODE_KIL:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
+ break;
+ case OPCODE_LG2:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
+ break;
+ case OPCODE_LIT:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
+ break;
+ case OPCODE_LRP:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
+ break;
+ case OPCODE_MAD:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
+ break;
+ case OPCODE_MAX:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
+ break;
+ case OPCODE_MIN:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
+ break;
+ case OPCODE_MOV:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
+ break;
+ case OPCODE_MUL:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
+ break;
+ case OPCODE_POW:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
+ break;
+ case OPCODE_RCP:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
+ break;
+ case OPCODE_RSQ:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
+ tgsi_util_set_full_src_register_sign_mode (&fullinst->FullSrcRegisters[0],
+ TGSI_UTIL_SIGN_CLEAR);
+ break;
+ case OPCODE_SCS:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
+ fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
+ break;
+ case OPCODE_SGE:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
+ break;
+ case OPCODE_SIN:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
+ break;
+ case OPCODE_SLT:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
+ break;
+ case OPCODE_SUB:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
+ break;
+ case OPCODE_SWZ:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
+ break;
+ case OPCODE_TEX:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
+ fullinst->Instruction.NumSrcRegs = 2;
+ fullinst->InstructionExtTexture.Texture = map_texture_target (inst->TexSrcTarget);
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
+ break;
+ case OPCODE_TXB:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
+ fullinst->Instruction.NumSrcRegs = 2;
+ fullinst->InstructionExtTexture.Texture = map_texture_target (inst->TexSrcTarget);
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
+ break;
+ case OPCODE_TXP:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
+ fullinst->Instruction.NumSrcRegs = 2;
+ fullinst->InstructionExtTexture.Texture = map_texture_target (inst->TexSrcTarget);
+ fullinst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide = TGSI_EXTSWIZZLE_W;
+ fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
+ fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
+ break;
+ case OPCODE_XPD:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
+ fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
+ break;
+ case OPCODE_END:
+ return GL_TRUE;
+ default:
+ assert (0);
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean
+tgsi_compile_fp_program( const struct gl_fragment_program *program,
+ struct tgsi_token *tokens,
+ GLuint max_token_count,
+ GLuint *token_count )
+{
+ GLuint i, ti;
+ struct tgsi_header *header;
+ struct tgsi_full_declaration fulldecl;
+ struct tgsi_full_instruction fullinst;
+ struct tgsi_full_dst_register *fulldst;
+ struct tgsi_full_src_register *fullsrc;
+ GLuint inputs_read;
+
+ *(struct tgsi_version *) &tokens[0] = tgsi_build_version ();
+
+ header = (struct tgsi_header *) &tokens[1];
+ *header = tgsi_build_header ();
+
+ ti = 2;
+
+ /*
+ * Input 0 is always read, at least implicitly by the instruction generated
+ * above, so mark it as used.
+ */
+ inputs_read = program->Base.InputsRead | 1;
+
+ /*
+ * Declare input attributes.
+ */
+ fulldecl = tgsi_default_full_declaration();
+
+ fulldecl.Declaration.File = TGSI_FILE_INPUT;
+ fulldecl.Declaration.Declare = TGSI_DECLARE_RANGE;
+ fulldecl.Declaration.Interpolate = 1;
+
+ /*
+ * Do not interpolate fragment position.
+ */
+ fulldecl.u.DeclarationRange.First = 0;
+ fulldecl.u.DeclarationRange.Last = 0;
+
+ fulldecl.Interpolation.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+
+ ti += tgsi_build_full_declaration(
+ &fulldecl,
+ &tokens[ti],
+ header,
+ max_token_count - ti );
+
+ /*
+ * Interpolate generic attributes.
+ */
+ fulldecl.u.DeclarationRange.First = 1;
+ fulldecl.u.DeclarationRange.Last = 1;
+ for( i = 1; i < 32; i++ ) {
+ if( inputs_read & (1 << i) ) {
+ fulldecl.u.DeclarationRange.Last++;
+ }
+ }
+
+ fulldecl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR;
+
+ ti += tgsi_build_full_declaration(
+ &fulldecl,
+ &tokens[ti],
+ header,
+ max_token_count - ti );
+
+ /*
+ * Copy input fragment xyz to output xyz.
+ * If the shader writes depth, do not copy the z component.
+ */
+
+ fullinst = tgsi_default_full_instruction ();
+
+ fullinst.Instruction.Opcode = TGSI_OPCODE_MOV;
+ fullinst.Instruction.NumDstRegs = 1;
+ fullinst.Instruction.NumSrcRegs = 1;
+
+ fulldst = &fullinst.FullDstRegisters[0];
+ fulldst->DstRegister.File = TGSI_FILE_OUTPUT;
+ fulldst->DstRegister.Index = 0;
+ if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
+ fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XY;
+ } else {
+ fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
+ }
+
+ fullsrc = &fullinst.FullSrcRegisters[0];
+ fullsrc->SrcRegister.File = TGSI_FILE_INPUT;
+ fullsrc->SrcRegister.Index = 0;
+
+ ti += tgsi_build_full_instruction (&fullinst,
+ &tokens[ti],
+ header,
+ max_token_count - ti);
+
+ for( i = 0; i < program->Base.NumInstructions; i++ ) {
+ if (compile_instruction (&program->Base.Instructions[i],
+ &fullinst,
+ inputs_read,
+ TGSI_PROCESSOR_FRAGMENT)) {
+ assert (i == program->Base.NumInstructions - 1);
+ tgsi_dump (tokens, TGSI_DUMP_NO_IGNORED | TGSI_DUMP_NO_DEFAULT);
+ break;
+ }
+
+ ti += tgsi_build_full_instruction (&fullinst,
+ &tokens[ti],
+ header,
+ max_token_count - ti);
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+tgsi_compile_vp_program( const struct gl_vertex_program *program,
+ struct tgsi_token *tokens,
+ GLuint max_token_count,
+ GLuint *token_count )
+{
+ GLuint ii, ti;
+ struct tgsi_header *header;
+ struct tgsi_processor *processor;
+ struct tgsi_full_instruction fullinst;
+ GLuint inputs_read = ~0;
+
+ *(struct tgsi_version *) &tokens[0] = tgsi_build_version ();
+
+ header = (struct tgsi_header *) &tokens[1];
+ *header = tgsi_build_header ();
+
+ processor = (struct tgsi_processor *) &tokens[2];
+ *processor = tgsi_build_processor (TGSI_PROCESSOR_VERTEX, header);
+
+ ti = 3;
+
+ for (ii = 0; ii < program->Base.NumInstructions; ii++) {
+ if (compile_instruction (&program->Base.Instructions[ii],
+ &fullinst,
+ inputs_read,
+ TGSI_PROCESSOR_VERTEX)) {
+ assert (ii == program->Base.NumInstructions - 1);
+ tgsi_dump (tokens, TGSI_DUMP_NO_IGNORED | TGSI_DUMP_NO_DEFAULT);
+ break;
+ }
+
+ ti += tgsi_build_full_instruction (&fullinst,
+ &tokens[ti],
+ header,
+ max_token_count - ti);
+ }
+
+ return GL_TRUE;
+}
+
diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h new file mode 100644 index 0000000000..4c1141e579 --- /dev/null +++ b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.h @@ -0,0 +1,25 @@ +#if !defined MESA_TO_TGSI_H
+#define MESA_TO_TGSI_H
+
+#if defined __cplusplus
+extern "C" {
+#endif // defined __cplusplus
+
+GLboolean
+tgsi_mesa_compile_fp_program(
+ const struct gl_fragment_program *program,
+ struct tgsi_token *tokens,
+ GLuint maxTokens );
+
+GLboolean
+tgsi_mesa_compile_vp_program(
+ const struct gl_vertex_program *program,
+ struct tgsi_token *tokens,
+ GLuint maxTokens );
+
+#if defined __cplusplus
+} // extern "C"
+#endif // defined __cplusplus
+
+#endif // !defined MESA_TO_TGSI_H
+
diff --git a/src/mesa/pipe/tgsi/mesa/tgsi_mesa.h b/src/mesa/pipe/tgsi/mesa/tgsi_mesa.h new file mode 100644 index 0000000000..0053748fde --- /dev/null +++ b/src/mesa/pipe/tgsi/mesa/tgsi_mesa.h @@ -0,0 +1,8 @@ +#if !defined TGSI_MESA_H
+#define TGSI_MESA_H
+
+#include "../core/tgsi_core.h"
+#include "mesa_to_tgsi.h"
+
+#endif // !defined TGSI_MESA_H
+
diff --git a/src/mesa/pipe/tgsi/tgsi_platform.h b/src/mesa/pipe/tgsi/tgsi_platform.h new file mode 100644 index 0000000000..553f0b26a8 --- /dev/null +++ b/src/mesa/pipe/tgsi/tgsi_platform.h @@ -0,0 +1,18 @@ +#if !defined TGSI_PLATFORM_H +#define TGSI_PLATFORM_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +#include "imports.h" +#include "mtypes.h" +#include "prog_instruction.h" +#include "program.h" + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_PLATFORM_H + diff --git a/src/mesa/sources b/src/mesa/sources index 643e841b15..b1ff3798a6 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -179,6 +179,16 @@ SOFTPIPE_SOURCES = \ pipe/softpipe/sp_state_setup.c \ pipe/softpipe/sp_state_surface.c +TGSICORE_SOURCES = \ + pipe/tgsi/core/tgsi_build.c \ + pipe/tgsi/core/tgsi_dump.c \ + pipe/tgsi/core/tgsi_exec.c \ + pipe/tgsi/core/tgsi_parse.c \ + pipe/tgsi/core/tgsi_util.c + +TGSIMESA_SOURCES = \ + pipe/tgsi/mesa/mesa_to_tgsi.c + STATETRACKER_SOURCES = \ state_tracker/st_atom.c \ state_tracker/st_atom_alphatest.c \ @@ -344,8 +354,10 @@ SOLO_SOURCES = \ $(MATH_SOURCES) \ $(VBO_SOURCES) \ $(VF_SOURCES) \ - $(SOFTPIPE_SOURCES) \ - $(STATETRACKER_SOURCES) \ + $(SOFTPIPE_SOURCES) \ + $(TGSICORE_SOURCES) \ + $(TGSIMESA_SOURCES) \ + $(STATETRACKER_SOURCES) \ $(TNL_SOURCES) \ $(SHADER_SOURCES) \ $(SWRAST_SOURCES) \ @@ -391,4 +403,5 @@ INCLUDE_DIRS = \ -I$(TOP)/src/mesa/shader/grammar \ -I$(TOP)/src/mesa/shader/slang \ -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/mesa/pipe/tgsi diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 67a589ca8d..327b627722 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -41,6 +41,7 @@ #include "program.h" #include "programopt.h" #include "tnl/tnl.h" +#include "pipe/tgsi/mesa/tgsi_mesa.h" static void st_bind_program( GLcontext *ctx, @@ -89,7 +90,7 @@ static struct gl_program *st_new_program( GLcontext *ctx, static void st_delete_program( GLcontext *ctx, struct gl_program *prog ) -{ +{ _mesa_delete_program( ctx, prog ); } @@ -115,7 +116,7 @@ static void st_program_string_notify( GLcontext *ctx, st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM; - p->id = st->program_id++; + p->id = st->program_id++; #if 0 p->param_state = p->Base.Base.Parameters->StateFlags; p->translated = 0; @@ -128,6 +129,14 @@ static void st_program_string_notify( GLcontext *ctx, _mesa_append_fog_code(ctx, &p->Base); p->Base.FogOption = GL_NONE; } + + /* XXX: Not hooked-up yet. */ + { + struct tgsi_token tokens[1024]; + + tgsi_mesa_compile_fp_program( prog, tokens, 1024 ); + tgsi_dump( tokens, TGSI_DUMP_VERBOSE ); + } } } else if (target == GL_VERTEX_PROGRAM_ARB) { @@ -148,7 +157,6 @@ void st_init_cb_program( struct st_context *st ) */ st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - assert(functions->ProgramStringNotify == _tnl_program_string); functions->BindProgram = st_bind_program; diff --git a/src/mesa/state_tracker/st_texobj.c b/src/mesa/state_tracker/st_texobj.c index 455e89b6bd..eb5bdb2d08 100644 --- a/src/mesa/state_tracker/st_texobj.c +++ b/src/mesa/state_tracker/st_texobj.c @@ -52,7 +52,8 @@ create_texture_object(struct gl_texture_object *texObj) if (!pto) return NULL; - assert(texObj->Complete); + /* XXX: Member not defined. Comment-out to get it compile. */ + /*assert(texObj->Complete);*/ switch (texObj->Target) { case GL_TEXTURE_1D: |