예제 #1
0
파일: tgsi_build.c 프로젝트: Plombo/mesa
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;
}
예제 #2
0
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;
}