unsigned tgsi_build_full_instruction( const struct tgsi_full_instruction *full_inst, struct tgsi_token *tokens, struct tgsi_header *header, unsigned maxsize ) { unsigned size = 0; unsigned 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.Predicate, full_inst->Instruction.NumDstRegs, full_inst->Instruction.NumSrcRegs, header); prev_token = (struct tgsi_token *) instruction; if (full_inst->Instruction.Predicate) { struct tgsi_instruction_predicate *instruction_predicate; if (maxsize <= size) { return 0; } instruction_predicate = (struct tgsi_instruction_predicate *)&tokens[size]; size++; *instruction_predicate = tgsi_build_instruction_predicate(full_inst->Predicate.Index, full_inst->Predicate.Negate, full_inst->Predicate.SwizzleX, full_inst->Predicate.SwizzleY, full_inst->Predicate.SwizzleZ, full_inst->Predicate.SwizzleW, instruction, header); } if (full_inst->Instruction.Label) { struct tgsi_instruction_label *instruction_label; if( maxsize <= size ) return 0; instruction_label = (struct tgsi_instruction_label *) &tokens[size]; size++; *instruction_label = tgsi_build_instruction_label( full_inst->Label.Label, prev_token, instruction, header ); prev_token = (struct tgsi_token *) instruction_label; } if (full_inst->Instruction.Texture) { struct tgsi_instruction_texture *instruction_texture; if( maxsize <= size ) return 0; instruction_texture = (struct tgsi_instruction_texture *) &tokens[size]; size++; *instruction_texture = tgsi_build_instruction_texture( full_inst->Texture.Texture, full_inst->Texture.NumOffsets, prev_token, instruction, header ); prev_token = (struct tgsi_token *) instruction_texture; for (i = 0; i < full_inst->Texture.NumOffsets; i++) { struct tgsi_texture_offset *texture_offset; if ( maxsize <= size ) return 0; texture_offset = (struct tgsi_texture_offset *)&tokens[size]; size++; *texture_offset = tgsi_build_texture_offset( full_inst->TexOffsets[i].Index, full_inst->TexOffsets[i].File, full_inst->TexOffsets[i].SwizzleX, full_inst->TexOffsets[i].SwizzleY, full_inst->TexOffsets[i].SwizzleZ, prev_token, instruction, header); prev_token = (struct tgsi_token *) texture_offset; } } for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; struct tgsi_dst_register *dst_register; if( maxsize <= size ) return 0; dst_register = (struct tgsi_dst_register *) &tokens[size]; size++; *dst_register = tgsi_build_dst_register( reg->Register.File, reg->Register.WriteMask, reg->Register.Indirect, reg->Register.Dimension, reg->Register.Index, instruction, header ); if( reg->Register.Indirect ) { struct tgsi_ind_register *ind; if( maxsize <= size ) return 0; ind = (struct tgsi_ind_register *) &tokens[size]; size++; *ind = tgsi_build_ind_register( reg->Indirect.File, reg->Indirect.Swizzle, reg->Indirect.Index, reg->Indirect.ArrayID, instruction, header ); } if( reg->Register.Dimension ) { struct tgsi_dimension *dim; assert( !reg->Dimension.Dimension ); if( maxsize <= size ) return 0; dim = (struct tgsi_dimension *) &tokens[size]; size++; *dim = tgsi_build_dimension( reg->Dimension.Indirect, reg->Dimension.Index, instruction, header ); if( reg->Dimension.Indirect ) { struct tgsi_ind_register *ind; if( maxsize <= size ) return 0; ind = (struct tgsi_ind_register *) &tokens[size]; size++; *ind = tgsi_build_ind_register( reg->DimIndirect.File, reg->DimIndirect.Swizzle, reg->DimIndirect.Index, reg->DimIndirect.ArrayID, instruction, header ); } } } for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { const struct tgsi_full_src_register *reg = &full_inst->Src[i]; struct tgsi_src_register *src_register; if( maxsize <= size ) return 0; src_register = (struct tgsi_src_register *) &tokens[size]; size++; *src_register = tgsi_build_src_register( reg->Register.File, reg->Register.SwizzleX, reg->Register.SwizzleY, reg->Register.SwizzleZ, reg->Register.SwizzleW, reg->Register.Negate, reg->Register.Absolute, reg->Register.Indirect, reg->Register.Dimension, reg->Register.Index, instruction, header ); if( reg->Register.Indirect ) { struct tgsi_ind_register *ind; if( maxsize <= size ) return 0; ind = (struct tgsi_ind_register *) &tokens[size]; size++; *ind = tgsi_build_ind_register( reg->Indirect.File, reg->Indirect.Swizzle, reg->Indirect.Index, reg->Indirect.ArrayID, instruction, header ); } if( reg->Register.Dimension ) { struct tgsi_dimension *dim; assert( !reg->Dimension.Dimension ); if( maxsize <= size ) return 0; dim = (struct tgsi_dimension *) &tokens[size]; size++; *dim = tgsi_build_dimension( reg->Dimension.Indirect, reg->Dimension.Index, instruction, header ); if( reg->Dimension.Indirect ) { struct tgsi_ind_register *ind; if( maxsize <= size ) return 0; ind = (struct tgsi_ind_register *) &tokens[size]; size++; *ind = tgsi_build_ind_register( reg->DimIndirect.File, reg->DimIndirect.Swizzle, reg->DimIndirect.Index, reg->DimIndirect.ArrayID, instruction, header ); } } } return size; }
unsigned tgsi_build_full_instruction( const struct tgsi_full_instruction *full_inst, struct tgsi_token *tokens, struct tgsi_header *header, unsigned maxsize ) { unsigned size = 0; unsigned 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, 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.Indirect, 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; } if( reg->DstRegister.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->DstRegisterInd.File, reg->DstRegisterInd.SwizzleX, reg->DstRegisterInd.SwizzleY, reg->DstRegisterInd.SwizzleZ, reg->DstRegisterInd.SwizzleW, reg->DstRegisterInd.Negate, reg->DstRegisterInd.Indirect, reg->DstRegisterInd.Dimension, reg->DstRegisterInd.Index, instruction, header ); } } 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; /* Use of the extended swizzle requires the simple swizzle to be identity. */ assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X ); assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y ); assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z ); assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W ); assert( reg->SrcRegister.Negate == FALSE ); 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, 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; }