std::string FragmentProgramDecompiler::GetCond() { if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq) { return "true"; } else if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq) { return "false"; } static const char f[4] = { 'x', 'y', 'z', 'w' }; std::string swizzle, cond; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; if (src0.exec_if_gr && src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SGE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_lt && src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SLE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_gr && src0.exec_if_lt) cond = compareFunction(COMPARE::FUNCTION_SNE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_gr) cond = compareFunction(COMPARE::FUNCTION_SGT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_lt) cond = compareFunction(COMPARE::FUNCTION_SLT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else //if(src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); return "any(" + cond + ")"; }
std::string GLFragmentDecompilerThread::GetCond() { if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq) { return "true"; } else if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq) { return "false"; } static const char f[4] = { 'x', 'y', 'z', 'w' }; std::string swizzle, cond; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; if (src0.exec_if_gr && src0.exec_if_eq) { cond = "greaterThanEqual"; } else if (src0.exec_if_lt && src0.exec_if_eq) { cond = "lessThanEqual"; } else if (src0.exec_if_gr && src0.exec_if_lt) { cond = "notEqual"; } else if (src0.exec_if_gr) { cond = "greaterThan"; } else if (src0.exec_if_lt) { cond = "lessThan"; } else //if(src0.exec_if_eq) { cond = "equal"; } return "any(" + cond + "(" + AddCond() + swizzle + ", vec4(0.0)))"; }
void FragmentProgramDecompiler::AddCodeCond(const std::string& dst, const std::string& src) { if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq) { AddCode(dst + " = " + src + ";"); return; } if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq) { AddCode("//" + dst + " = " + src + ";"); return; } static const char f[4] = { 'x', 'y', 'z', 'w' }; std::string swizzle, cond; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; if (src0.exec_if_gr && src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SGE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_lt && src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SLE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_gr && src0.exec_if_lt) cond = compareFunction(COMPARE::FUNCTION_SNE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_gr) cond = compareFunction(COMPARE::FUNCTION_SGT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else if (src0.exec_if_lt) cond = compareFunction(COMPARE::FUNCTION_SLT, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); else //if(src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); ShaderVariable dst_var(dst); dst_var.symplify(); //const char *c_mask = f; if (dst_var.swizzles[0].length() == 1) { AddCode("if (" + cond + ".x) " + dst + " = " + src + ";"); } else { for (int i = 0; i < dst_var.swizzles[0].length(); ++i) { AddCode("if (" + cond + "." + f[i] + ") " + dst + "." + f[i] + " = " + src + "." + f[i] + ";"); } } }
void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask) { if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return; const std::string mask = GetMask(); std::string cond; if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq) { static const char f[4] = {'x', 'y', 'z', 'w'}; std::string swizzle; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; if(src0.exec_if_gr && src0.exec_if_eq) { cond = "greaterThanEqual"; } else if(src0.exec_if_lt && src0.exec_if_eq) { cond = "lessThanEqual"; } else if(src0.exec_if_gr && src0.exec_if_lt) { cond = "notEqual"; } else if(src0.exec_if_gr) { cond = "greaterThan"; } else if(src0.exec_if_lt) { cond = "lessThan"; } else //if(src0.exec_if_eq) { cond = "equal"; } cond = "if(all(" + cond + "(" + AddCond(dst.no_dest) + swizzle + ", vec4(0.0)))) "; } if(src1.scale) { switch(src1.scale) { case 1: code = "(" + code + " * 2)"; break; case 2: code = "(" + code + " * 4)"; break; case 3: code = "(" + code + " * 8)"; break; case 5: code = "(" + code + " / 2)"; break; case 6: code = "(" + code + " / 4)"; break; case 7: code = "(" + code + " / 8)"; break; default: ConLog.Error("Bad scale: %d", fmt::by_value(src1.scale)); Emu.Pause(); break; } } if(dst.saturate) { code = "clamp(" + code + ", 0.0, 1.0)"; } std::string dest; if(dst.no_dest) { if(dst.set_cond) { dest = m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index)); } } else { dest = AddReg(dst.dest_reg, dst.fp16); } code = cond + (dest.length() ? dest + mask + " = " : "") + code + (append_mask ? mask : ""); main += "\t" + code + ";\n"; }
void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask) { if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return; const std::string mask = GetMask().c_str(); std::string cond = ""; if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq) { static const char f[4] = {'x', 'y', 'z', 'w'}; std::string swizzle = ""; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; if(src0.exec_if_gr && src0.exec_if_eq) { cond = "greaterThanEqual"; } else if(src0.exec_if_lt && src0.exec_if_eq) { cond = "lessThanEqual"; } else if(src0.exec_if_gr && src0.exec_if_lt) { cond = "notEqual"; } else if(src0.exec_if_gr) { cond = "greaterThan"; } else if(src0.exec_if_lt) { cond = "lessThan"; } else //if(src0.exec_if_eq) { cond = "equal"; } cond = std::string("if(all(" + cond + "(" + AddCond(dst.no_dest) + "." + swizzle +", vec4(0, 0, 0, 0)))) "); //ConLog.Error("cond! [eq: %d gr: %d lt: %d] (%s)", src0.exec_if_eq, src0.exec_if_gr, src0.exec_if_lt, cond); //Emu.Pause(); //return; } if(src1.scale) { switch(src1.scale) { case 1: code = "(" + code + " * 2)"; break; case 2: code = "(" + code + " * 4)"; break; case 3: code = "(" + code + " * 8)"; break; case 5: code = "(" + code + " / 2)"; break; case 6: code = "(" + code + " / 4)"; break; case 7: code = "(" + code + " / 8)"; break; default: ConLog.Error("Bad scale: %d", src1.scale); Emu.Pause(); break; } } if(dst.saturate) { code = "clamp(" + code + ", 0.0, 1.0)"; } code = cond + (dst.set_cond ? m_parr.AddParam(PARAM_NONE , "vec4", std::string(dst.fp16 ? "hc" : "rc") + std::to_string(src0.cond_reg_index)) : AddReg(dst.dest_reg, dst.fp16)) + mask + " = " + code + (append_mask ? mask : ""); main += "\t" + code + ";\n"; }
void GLFragmentDecompilerThread::AddCodeCond(const std::string& dst, const std::string& src) { if (src0.exec_if_gr && src0.exec_if_lt && src0.exec_if_eq) { AddCode(dst + " = " + src + ";"); return; } if (!src0.exec_if_gr && !src0.exec_if_lt && !src0.exec_if_eq) { AddCode("//" + dst + " = " + src + ";"); return; } static const char f[4] = { 'x', 'y', 'z', 'w' }; std::string swizzle, cond; swizzle += f[src0.cond_swizzle_x]; swizzle += f[src0.cond_swizzle_y]; swizzle += f[src0.cond_swizzle_z]; swizzle += f[src0.cond_swizzle_w]; swizzle = swizzle == "xyzw" ? "" : "." + swizzle; if (src0.exec_if_gr && src0.exec_if_eq) { cond = "greaterThanEqual"; } else if (src0.exec_if_lt && src0.exec_if_eq) { cond = "lessThanEqual"; } else if (src0.exec_if_gr && src0.exec_if_lt) { cond = "notEqual"; } else if (src0.exec_if_gr) { cond = "greaterThan"; } else if (src0.exec_if_lt) { cond = "lessThan"; } else //if(src0.exec_if_eq) { cond = "equal"; } cond = cond + "(" + AddCond() + swizzle + ", vec4(0.0))"; ShaderVar dst_var(dst); dst_var.symplify(); //const char *c_mask = f; if (dst_var.swizzles[0].length() == 1) { AddCode("if (" + cond + ".x) " + dst + " = vec4(" + src + ").x;"); } else { for (int i = 0; i < dst_var.swizzles[0].length(); ++i) { AddCode("if (" + cond + "." + f[i] + ") " + dst + "." + f[i] + " = " + src + "." + f[i] + ";"); } } }
//(1)支持and与or以构建复杂的条件 //(2)支持=与!=操作 //(3)值用单引号扩起(两个连续单引号表示一个单引号值) //(4)日期的值格式为:[a,b];[a,b);(a,b];(a,b); //(5)Host,Date,App,Module,Func,File,Key,Level,DMN,AIN,Line bool CLogChooser::AddChooser(const char* sCond) { bool bFirst = true; const char* sWhere = sCond; m_oMutex.Leave(); AddGroup(); if(sCond)while(sCond[0]) { bool bNot, bIncBeg, bIncEnd; CString oName, oVal1, oVal2; if(!sCond[0]) break; if(GetIdentifier(sCond, oName)) { RemoveEmptyGroup(); m_oMutex.Leave(); FocpError(("CLogChooser::AddChooser(%u:%s): get compare item failure", sCond-sWhere, sWhere)); return false; } if(!bFirst) { if(!oName.Compare("and", false)) continue; if(!oName.Compare("or", false)) { AddGroup(); continue; } } bFirst = false; uint32 nRet, nType = GetItemType(oName); if(nType >= 11) { RemoveEmptyGroup(); m_oMutex.Leave(); FocpError(("CLogChooser::AddChooser(%u:%s): the item '%s' is invalid", sCond-sWhere, sWhere, oName.GetStr())); return false; } if(GetOperator(sCond, bNot)) { RemoveEmptyGroup(); m_oMutex.Leave(); FocpError(("CLogChooser::AddChooser(%u:%s): get oprand failure", sCond-sWhere, sWhere)); return false; } if(nType == 1) nRet = GetDateTime(sCond, oVal1, oVal2, bIncBeg, bIncEnd); else if(nType >= 7) nRet = GetInt(sCond, oVal1); else nRet = GetString(sCond, oVal1); if(nRet) { RemoveEmptyGroup(); m_oMutex.Leave(); FocpError(("CLogChooser::AddChooser(%u:%s): get value failure", sCond-sWhere, sWhere)); return false; } AddCond(nType, bNot, oVal1, oVal2, bIncBeg, bIncEnd); } RemoveEmptyGroup(); m_oMutex.Leave(); return true; }