コード例 #1
0
ファイル: hlsl_alu.cpp プロジェクト: 7heaven/wiiu-emu
void translateAluDestStart(GenerateState &state, AluInstruction *ins)
{
   if (ins->unit != AluInstruction::T) {
      state.out << "PV" << '.';
      translateChannel(state, static_cast<latte::alu::Channel::Channel>(ins->unit));
   } else {
      state.out << "PS";
   }

   state.out << " = ";

   if (ins->writeMask) {
      state.out << 'R' << ins->dest.id << '.';
      translateChannel(state, ins->dest.chan);
      state.out << " = ";
   }

   switch (ins->outputModifier) {
   case latte::alu::OutputModifier::Multiply2:
   case latte::alu::OutputModifier::Multiply4:
   case latte::alu::OutputModifier::Divide2:
      state.out << '(';
      break;
   }

   if (ins->dest.clamp) {
      state.out << "clamp(";
   }
}
コード例 #2
0
ファイル: glsl_alu.cpp プロジェクト: Subv/decaf-emu
void translateAluDestStart(GenerateState &state, AluInstruction *ins)
{
   if (ins->unit != latte::SQ_CHAN_T) {
      if (state.shader->pvUsed.find(ins->groupPC) != state.shader->pvUsed.end()) {
         if (state.shader->pvUsed.find(ins->groupPC - 1) != state.shader->pvUsed.end()) {
            // If we read and write PV in this group we must use a temp to prevent clash
            state.out << "PVo.";
         } else {
            state.out << "PV.";
         }

         if (ins->isReduction) {
            // Reduction targets PV.x always
            state.out << 'x';
         } else {
            translateChannel(state, ins->unit);
         }

         state.out << " = ";
      }
   } else {
      if (state.shader->psUsed.find(ins->groupPC) != state.shader->psUsed.end()) {
         if (state.shader->pvUsed.find(ins->groupPC - 1) != state.shader->pvUsed.end()) {
            state.out << "PSo = ";
         } else {
            state.out << "PS = ";
         }
      }
   }

   if (ins->writeMask) {
      state.out << 'R' << ins->dst.sel << '.';
      translateChannel(state, ins->dst.chan);
      state.out << " = ";
   }

   if (ins->dst.type == ValueType::Uint) {
      state.out << "uintBitsToFloat(";
   } else if (ins->dst.type == ValueType::Int) {
      state.out << "intBitsToFloat(";
   }

   switch (ins->outputModifier) {
   case latte::SQ_ALU_OMOD_M2:
   case latte::SQ_ALU_OMOD_M4:
   case latte::SQ_ALU_OMOD_D2:
      state.out << '(';
      break;
   }

   if (ins->dst.clamp) {
      state.out << "clamp(";
   }
}
コード例 #3
0
ファイル: hlsl_alu.cpp プロジェクト: 7heaven/wiiu-emu
void translateAluSource(GenerateState &state, AluSource &src)
{
   if (src.absolute) {
      state.out << "abs(";
   }

   if (src.negate) {
      state.out << '-';
   }

   switch (src.type) {
   case AluSource::Register:
      state.out << 'R' << src.id;
      break;
   case AluSource::KcacheBank0:
      state.out << "KcackeBank0_" << src.id;
      break;
   case AluSource::KcacheBank1:
      state.out << "KcackeBank1_" << src.id;
      break;
   case AluSource::PreviousVector:
      state.out << "PV";
      break;
   case AluSource::PreviousScalar:
      state.out << "PS";
      break;
   case AluSource::ConstantFile:
      state.out << 'C' << src.id;
      break;
   case AluSource::ConstantFloat:
      state.out.write("{:.6f}f", src.floatValue);
      break;
   case AluSource::ConstantDouble:
      state.out.write("{:.6f}", src.doubleValue);
      break;
   case AluSource::ConstantInt:
      state.out << src.intValue;
      break;
   }

   switch (src.type) {
   case AluSource::Register:
   case AluSource::KcacheBank0:
   case AluSource::KcacheBank1:
   case AluSource::ConstantFile:
   case AluSource::PreviousVector:
      state.out << '.';
      translateChannel(state, src.chan);
   }

   if (src.absolute) {
      state.out << ")";
   }
}
コード例 #4
0
ファイル: glsl_alu.cpp プロジェクト: Subv/decaf-emu
void translateAluSource(GenerateState &state, const AluInstruction *ins, const AluSource &src)
{
   bool didTypeConversion = false;
   bool doChannelSelect = false;

   if (src.absolute) {
      state.out << "abs(";
   }

   if (src.negate) {
      state.out << '-';
   }

   if ((src.sel >= latte::SQ_ALU_REGISTER_0 && src.sel <= latte::SQ_ALU_REGISTER_127)
    || (src.sel >= latte::SQ_ALU_KCACHE_BANK0_0 && src.sel <= latte::SQ_ALU_KCACHE_BANK0_31)
    || (src.sel >= latte::SQ_ALU_KCACHE_BANK1_0 && src.sel <= latte::SQ_ALU_KCACHE_BANK1_31)
    || (src.sel >= latte::SQ_ALU_SRC_CONST_FILE_0 && src.sel <= latte::SQ_ALU_SRC_CONST_FILE_255)) {
      // Register, uniform register, uniform block must bit cast
      if (src.type == ValueType::Int) {
         state.out << "floatBitsToInt(";
         didTypeConversion = true;
      } else if (src.type == ValueType::Uint) {
         state.out << "floatBitsToUint(";
         didTypeConversion = true;
      }
   } else {
      switch (src.sel) {
      case latte::SQ_ALU_SRC_PV:
      case latte::SQ_ALU_SRC_PS:
         // PV, PS is bit cast
         if (src.type == ValueType::Int) {
            state.out << "floatBitsToInt(";
            didTypeConversion = true;
         } else if (src.type == ValueType::Uint) {
            state.out << "floatBitsToUint(";
            didTypeConversion = true;
         }
         break;
      case latte::SQ_ALU_SRC_LDS_OQ_A:
      case latte::SQ_ALU_SRC_LDS_OQ_B:
      case latte::SQ_ALU_SRC_LDS_OQ_A_POP:
      case latte::SQ_ALU_SRC_LDS_OQ_B_POP:
      case latte::SQ_ALU_SRC_LDS_DIRECT_A:
      case latte::SQ_ALU_SRC_LDS_DIRECT_B:
      case latte::SQ_ALU_SRC_TIME_HI:
      case latte::SQ_ALU_SRC_TIME_LO:
      case latte::SQ_ALU_SRC_MASK_HI:
      case latte::SQ_ALU_SRC_MASK_LO:
      case latte::SQ_ALU_SRC_HW_WAVE_ID:
      case latte::SQ_ALU_SRC_SIMD_ID:
      case latte::SQ_ALU_SRC_SE_ID:
      case latte::SQ_ALU_SRC_HW_THREADGRP_ID:
      case latte::SQ_ALU_SRC_WAVE_ID_IN_GRP:
      case latte::SQ_ALU_SRC_NUM_THREADGRP_WAVES:
      case latte::SQ_ALU_SRC_HW_ALU_ODD:
      case latte::SQ_ALU_SRC_LOOP_IDX:
      case latte::SQ_ALU_SRC_PARAM_BASE_ADDR:
      case latte::SQ_ALU_SRC_NEW_PRIM_MASK:
      case latte::SQ_ALU_SRC_PRIM_MASK_HI:
      case latte::SQ_ALU_SRC_PRIM_MASK_LO:
      case latte::SQ_ALU_SRC_1_DBL_L:
      case latte::SQ_ALU_SRC_1_DBL_M:
      case latte::SQ_ALU_SRC_0_5_DBL_L:
      case latte::SQ_ALU_SRC_0_5_DBL_M:
      case latte::SQ_ALU_SRC_0:
      case latte::SQ_ALU_SRC_1:
      case latte::SQ_ALU_SRC_0_5:
         // Other is value cast
         if (src.type == ValueType::Int) {
            state.out << "int(";
            didTypeConversion = true;
         } else if (src.type == ValueType::Uint) {
            state.out << "uint(";
            didTypeConversion = true;
         }
         break;
      case latte::SQ_ALU_SRC_1_INT:
      case latte::SQ_ALU_SRC_M_1_INT:
      case latte::SQ_ALU_SRC_LITERAL:
         // No need for type conversion
         break;
      }
   }

   // Output register name
   if (src.sel >= latte::SQ_ALU_REGISTER_0 && src.sel <= latte::SQ_ALU_REGISTER_127) {
      state.out << 'R' << (src.sel - latte::SQ_ALU_REGISTER_0);
      doChannelSelect = true;
   } else if ((src.sel >= latte::SQ_ALU_KCACHE_BANK0_0 && src.sel <= latte::SQ_ALU_KCACHE_BANK0_31)
           || (src.sel >= latte::SQ_ALU_KCACHE_BANK1_0 && src.sel <= latte::SQ_ALU_KCACHE_BANK1_31)) {
      auto index = (src.sel >= latte::SQ_ALU_KCACHE_BANK1_0) ? 1 : 0;
      auto addr = ins->parent->kcache[index].addr;
      auto bank = ins->parent->kcache[index].bank;
      auto mode = ins->parent->kcache[index].mode;
      auto id = (addr * 16);

      if (src.sel >= latte::SQ_ALU_KCACHE_BANK1_0) {
         id += src.sel - latte::SQ_ALU_KCACHE_BANK1_0;
      } else {
         id += src.sel - latte::SQ_ALU_KCACHE_BANK0_0;
      }

      if (mode == latte::SQ_CF_KCACHE_LOCK_LOOP_INDEX) {
         throw std::logic_error("Unimplemented kcache lock mode SQ_CF_KCACHE_LOCK_LOOP_INDEX");
      } else if (mode == latte::SQ_CF_KCACHE_NOP) {
         throw std::logic_error("Invalid kcache lock mode SQ_CF_KCACHE_NOP");
      }

      if (state.shader->type == latte::Shader::Vertex) {
         state.out << "VB[" << bank << "].values[" << id;
      } else if (state.shader->type == latte::Shader::Pixel) {
         state.out << "PB[" << bank << "].values[" << id;
      } else {
         throw std::logic_error("Unexpected shader type");
      }

      if (src.rel) {
         state.out << " + ";
         translateIndex(state, ins->indexMode);
      }

      state.out << ']';
      doChannelSelect = true;
   } else if (src.sel >= latte::SQ_ALU_SRC_CONST_FILE_0 && src.sel <= latte::SQ_ALU_SRC_CONST_FILE_255) {
      if (state.shader->type == latte::Shader::Vertex) {
         state.out << "VR[" << (src.sel - latte::SQ_ALU_SRC_CONST_FILE_0);
      } else if (state.shader->type == latte::Shader::Pixel) {
         state.out << "PR[" << (src.sel - latte::SQ_ALU_SRC_CONST_FILE_0);
      } else {
         throw std::runtime_error("Unexpected shader type for ConstantFile");
      }

      if (src.rel) {
         state.out << " + ";
         translateIndex(state, ins->indexMode);
      }

      state.out << ']';
      doChannelSelect = true;
   } else {
      switch (src.sel) {
      case latte::SQ_ALU_SRC_PV:
         state.out << "PV";
         doChannelSelect = true;
         break;
      case latte::SQ_ALU_SRC_PS:
         state.out << "PS";
         break;
      case latte::SQ_ALU_SRC_0:
         state.out << "0.0f";
         break;
      case latte::SQ_ALU_SRC_1:
         state.out << "1.0f";
         break;
      case latte::SQ_ALU_SRC_0_5:
         state.out << "0.5f";
         break;
      case latte::SQ_ALU_SRC_1_INT:
         state.out << "1";
         break;
      case latte::SQ_ALU_SRC_M_1_INT:
         state.out << "-1";
         break;
      case latte::SQ_ALU_SRC_LITERAL:
         if (src.type == ValueType::Float) {
            state.out.write("{:.6f}f", src.literalFloat);
         } else if (src.type == ValueType::Int) {
            state.out << src.literalInt;
         } else if (src.type == ValueType::Uint) {
            state.out << src.literalUint;
         }
         break;
      case latte::SQ_ALU_SRC_1_DBL_L:
      case latte::SQ_ALU_SRC_1_DBL_M:
      case latte::SQ_ALU_SRC_0_5_DBL_L:
      case latte::SQ_ALU_SRC_0_5_DBL_M:
      case latte::SQ_ALU_SRC_LDS_OQ_A:
      case latte::SQ_ALU_SRC_LDS_OQ_B:
      case latte::SQ_ALU_SRC_LDS_OQ_A_POP:
      case latte::SQ_ALU_SRC_LDS_OQ_B_POP:
      case latte::SQ_ALU_SRC_LDS_DIRECT_A:
      case latte::SQ_ALU_SRC_LDS_DIRECT_B:
      case latte::SQ_ALU_SRC_TIME_HI:
      case latte::SQ_ALU_SRC_TIME_LO:
      case latte::SQ_ALU_SRC_MASK_HI:
      case latte::SQ_ALU_SRC_MASK_LO:
      case latte::SQ_ALU_SRC_HW_WAVE_ID:
      case latte::SQ_ALU_SRC_SIMD_ID:
      case latte::SQ_ALU_SRC_SE_ID:
      case latte::SQ_ALU_SRC_HW_THREADGRP_ID:
      case latte::SQ_ALU_SRC_WAVE_ID_IN_GRP:
      case latte::SQ_ALU_SRC_NUM_THREADGRP_WAVES:
      case latte::SQ_ALU_SRC_HW_ALU_ODD:
      case latte::SQ_ALU_SRC_LOOP_IDX:
      case latte::SQ_ALU_SRC_PARAM_BASE_ADDR:
      case latte::SQ_ALU_SRC_NEW_PRIM_MASK:
      case latte::SQ_ALU_SRC_PRIM_MASK_HI:
      case latte::SQ_ALU_SRC_PRIM_MASK_LO:
      default:
         throw std::logic_error(fmt::format("Unsupported register used {}", src.sel));
         break;
      }
   }

   if (src.rel) {
      if (src.sel < latte::SQ_ALU_SRC_CONST_FILE_0 || src.sel > latte::SQ_ALU_SRC_CONST_FILE_255) {
         throw std::logic_error("Relative AluSource is only supported with uniform registers");
      }
   }

   if (doChannelSelect) {
      state.out << '.';
      translateChannel(state, src.chan);
   }

   if (didTypeConversion) {
      state.out << ')';
   }

   if (src.absolute) {
      state.out << ')';
   }
}