From 0ad4e91001b72238a752aedb4456145b9df26f57 Mon Sep 17 00:00:00 2001 From: sampletext32 Date: Fri, 5 Jun 2020 17:35:53 +0300 Subject: [PATCH] Avoid string reallocation in swizzle CgBinaryProgram --- rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp | 50 ++++++++------- rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp | 62 ++++++++++++------- .../RSX/Common/FragmentProgramDecompiler.cpp | 30 ++++++--- 3 files changed, 88 insertions(+), 54 deletions(-) diff --git a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp index be65ee68af..af43151d98 100644 --- a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp @@ -47,18 +47,17 @@ void CgBinaryDisasm::AddCodeAsm(const std::string& code) std::string CgBinaryDisasm::GetMask() { std::string ret; + ret.reserve(5); - static const char dst_mask[4] = - { - 'x', 'y', 'z', 'w' - }; + static constexpr std::string_view dst_mask = "xyzw"; + ret += '.'; if (dst.mask_x) ret += dst_mask[0]; if (dst.mask_y) ret += dst_mask[1]; if (dst.mask_z) ret += dst_mask[2]; if (dst.mask_w) ret += dst_mask[3]; - return ret.empty() || strncmp(ret.c_str(), dst_mask, 4) == 0 ? "" : ("." + ret); + return ret == "."sv || ret == ".xyzw"sv ? "" : (ret); } std::string CgBinaryDisasm::AddRegDisAsm(u32 index, int fp16) @@ -86,20 +85,25 @@ std::string CgBinaryDisasm::AddTexDisAsm() std::string CgBinaryDisasm::GetCondDisAsm() { - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle, cond; + swizzle.reserve(5); + 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 (swizzle == "xxxx") swizzle = "x"; - if (swizzle == "yyyy") swizzle = "y"; - if (swizzle == "zzzz") swizzle = "z"; - if (swizzle == "wwww") swizzle = "w"; + if (swizzle == ".xxxx") swizzle = ".x"; + else if (swizzle == ".yyyy") swizzle = ".y"; + else if (swizzle == ".zzzz") swizzle = ".z"; + else if (swizzle == ".wwww") swizzle = ".w"; - swizzle = swizzle == "xyzw" ? "" : "." + swizzle; + if (swizzle == ".xyzw"sv) + { + swizzle.clear(); + } if (src0.exec_if_gr && src0.exec_if_eq) { @@ -170,15 +174,14 @@ template std::string CgBinaryDisasm::GetSrcDisAsm(T src) "TEX6", "TEX7", "TEX8", "TEX9", "SSA" }; - const std::string perspective_correction = src2.perspective_corr ? "g" : "f"; - const std::string input_attr_reg = reg_table[dst.src_attr_reg_num]; - switch (dst.src_attr_reg_num) { case 0x00: ret += reg_table[0]; break; default: if (dst.src_attr_reg_num < std::size(reg_table)) { + const std::string perspective_correction = src2.perspective_corr ? "g" : "f"; + const std::string input_attr_reg = reg_table[dst.src_attr_reg_num]; ret += fmt::format("%s[%s]", perspective_correction.c_str(), input_attr_reg.c_str()); } else @@ -199,21 +202,26 @@ template std::string CgBinaryDisasm::GetSrcDisAsm(T src) break; } - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle; + swizzle.reserve(5); + swizzle += '.'; swizzle += f[src.swizzle_x]; swizzle += f[src.swizzle_y]; swizzle += f[src.swizzle_z]; swizzle += f[src.swizzle_w]; - if (swizzle == "xxxx") swizzle = "x"; - if (swizzle == "yyyy") swizzle = "y"; - if (swizzle == "zzzz") swizzle = "z"; - if (swizzle == "wwww") swizzle = "w"; - - if (strncmp(swizzle.c_str(), f, 4) != 0) ret += "." + swizzle; + if (swizzle == ".xxxx") swizzle = ".x"; + else if (swizzle == ".yyyy") swizzle = ".y"; + else if (swizzle == ".zzzz") swizzle = ".z"; + else if (swizzle == ".wwww") swizzle = ".w"; + if (swizzle != ".xyzw"sv) + { + ret += swizzle; + } + if (src.neg) ret = "-" + ret; if (src.abs) ret = "|" + ret + "|"; diff --git a/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp b/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp index 2d2ad61a33..d80d25c81d 100644 --- a/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryVertexProgram.cpp @@ -19,6 +19,8 @@ void CgBinaryDisasm::AddVecCodeDisasm(const std::string& code) std::string CgBinaryDisasm::GetMaskDisasm(bool is_sca) { std::string ret; + ret.reserve(5); + ret += '.'; if (is_sca) { @@ -35,7 +37,7 @@ std::string CgBinaryDisasm::GetMaskDisasm(bool is_sca) if (d3.vec_writemask_w) ret += "w"; } - return ret.empty() || ret == "xyzw" ? "" : ("." + ret); + return ret == "."sv || ret == ".xyzw"sv ? "" : (ret); } std::string CgBinaryDisasm::GetVecMaskDisasm() @@ -103,21 +105,25 @@ std::string CgBinaryDisasm::GetSRCDisasm(const u32 n) break; } - static const std::string f = "xyzw"; + static constexpr std::string_view f = "xyzw"; std::string swizzle; - + swizzle.reserve(5); + swizzle += '.'; swizzle += f[src[n].swz_x]; swizzle += f[src[n].swz_y]; swizzle += f[src[n].swz_z]; swizzle += f[src[n].swz_w]; - if (swizzle == "xxxx") swizzle = "x"; - if (swizzle == "yyyy") swizzle = "y"; - if (swizzle == "zzzz") swizzle = "z"; - if (swizzle == "wwww") swizzle = "w"; + if (swizzle == ".xxxx") swizzle = ".x"; + else if (swizzle == ".yyyy") swizzle = ".y"; + else if (swizzle == ".zzzz") swizzle = ".z"; + else if (swizzle == ".wwww") swizzle = ".w"; - if (swizzle != f) ret += '.' + swizzle; + if (swizzle != ".xyzw"sv) + { + ret += swizzle; + } bool abs = false; @@ -221,20 +227,25 @@ std::string CgBinaryDisasm::GetCondDisasm() "ERROR" }; - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle; + swizzle.reserve(5); + swizzle += '.'; swizzle += f[d0.mask_x]; swizzle += f[d0.mask_y]; swizzle += f[d0.mask_z]; swizzle += f[d0.mask_w]; - if (swizzle == "xxxx") swizzle = "x"; - if (swizzle == "yyyy") swizzle = "y"; - if (swizzle == "zzzz") swizzle = "z"; - if (swizzle == "wwww") swizzle = "w"; + if (swizzle == ".xxxx") swizzle = ".x"; + else if (swizzle == ".yyyy") swizzle = ".y"; + else if (swizzle == ".zzzz") swizzle = ".z"; + else if (swizzle == ".wwww") swizzle = ".w"; - swizzle = swizzle == "xyzw" ? "" : "." + swizzle; + if (swizzle == ".xyzw"sv) + { + swizzle.clear(); + } return fmt::format("(%s%s)", cond_string_table[d0.cond], swizzle.c_str()); } @@ -268,21 +279,26 @@ void CgBinaryDisasm::AddCodeCondDisasm(const std::string& dst, const std::string "ERROR" }; - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle; + swizzle.reserve(5); + swizzle += '.'; swizzle += f[d0.mask_x]; swizzle += f[d0.mask_y]; swizzle += f[d0.mask_z]; swizzle += f[d0.mask_w]; - if (swizzle == "xxxx") swizzle = "x"; - if (swizzle == "yyyy") swizzle = "y"; - if (swizzle == "zzzz") swizzle = "z"; - if (swizzle == "wwww") swizzle = "w"; - - swizzle = swizzle == "xyzw" ? "" : "." + swizzle; + if (swizzle == ".xxxx") swizzle = ".x"; + else if (swizzle == ".yyyy") swizzle = ".y"; + else if (swizzle == ".zzzz") swizzle = ".z"; + else if (swizzle == ".wwww") swizzle = ".w"; + if (swizzle == ".xyzw"sv) + { + swizzle.clear(); + } + std::string cond = fmt::format("%s%s", cond_string_table[d0.cond], swizzle.c_str()); AddCodeDisasm(dst + "(" + cond + ") " + ", " + src + ";"); } @@ -290,13 +306,13 @@ void CgBinaryDisasm::AddCodeCondDisasm(const std::string& dst, const std::string std::string CgBinaryDisasm::AddAddrMaskDisasm() { - static const char f[] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; return std::string(".") + f[d0.addr_swz]; } std::string CgBinaryDisasm::AddAddrRegDisasm() { - static const char f[] = { 'x', 'y', 'z', 'w' }; + //static constexpr std::string_view f = "xyzw"; return fmt::format("A%d", d0.addr_reg_sel_1) + AddAddrMaskDisasm(); } diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 8051b1d110..5ca7a4fc87 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -173,18 +173,17 @@ void FragmentProgramDecompiler::AddCode(const std::string& code) std::string FragmentProgramDecompiler::GetMask() { std::string ret; + ret.reserve(5); + + static constexpr std::string_view dst_mask = "xyzw"; - static const char dst_mask[4] = - { - 'x', 'y', 'z', 'w', - }; - + ret += '.'; if (dst.mask_x) ret += dst_mask[0]; if (dst.mask_y) ret += dst_mask[1]; if (dst.mask_z) ret += dst_mask[2]; if (dst.mask_w) ret += dst_mask[3]; - return ret.empty() || strncmp(ret.c_str(), dst_mask, 4) == 0 ? "" : ("." + ret); + return ret == "."sv || ret == ".xyzw"sv ? "" : (ret); } std::string FragmentProgramDecompiler::AddReg(u32 index, bool fp16) @@ -366,14 +365,20 @@ std::string FragmentProgramDecompiler::Format(const std::string& code, bool igno std::string FragmentProgramDecompiler::GetRawCond() { - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle, cond; + swizzle.reserve(5); + 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 (swizzle == ".xyzw"sv) + { + swizzle.clear(); + } if (src0.exec_if_gr && src0.exec_if_eq) cond = compareFunction(COMPARE::FUNCTION_SGE, AddCond() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)"); @@ -663,15 +668,20 @@ template std::string FragmentProgramDecompiler::GetSRC(T src) break; } - static const char f[4] = { 'x', 'y', 'z', 'w' }; + static constexpr std::string_view f = "xyzw"; std::string swizzle; + swizzle.reserve(5); + swizzle += '.'; swizzle += f[src.swizzle_x]; swizzle += f[src.swizzle_y]; swizzle += f[src.swizzle_z]; swizzle += f[src.swizzle_w]; - if (strncmp(swizzle.c_str(), f, 4) != 0) ret += "." + swizzle; + if (swizzle != ".xyzw"sv) + { + ret += swizzle; + } // Warning: Modifier order matters. e.g neg should be applied after precision clamping (tested with Naruto UNS) if (src.abs) ret = "abs(" + ret + ")";