diff --git a/rpcs3/Emu/RSX/Program/ShaderInterpreter.cpp b/rpcs3/Emu/RSX/Program/ShaderInterpreter.cpp index a01171b3e6..54ba46b28a 100644 --- a/rpcs3/Emu/RSX/Program/ShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/Program/ShaderInterpreter.cpp @@ -5,54 +5,67 @@ namespace program_common::interpreter { - std::vector get_interpreter_variants() - { - // Separable passes to fetch all possible variants - std::unordered_set fs_masks; - for (u32 fs_opt = COMPILER_OPT_FS_MIN, fs_opt_bit = fs_opt; - fs_opt <= COMPILER_OPT_FS_MAX; fs_opt++, fs_opt_bit <<= 1) - { - if (fs_opt_bit & COMPILER_OPT_ALPHA_TEST_MASK) - { - continue; - } + void bitrange_foreach(u32 min, u32 max, std::function func) + { + if (max <= min) + { + return; + } - fs_masks.insert(fs_opt); - } + const u32 shift = std::countr_zero(min); + const u32 a = min >> shift; + const u32 b = (max + max) >> shift; - // Now we add in the alpha testing variants for all fs variants. - // Only one alpha test type is usable at once - std::unordered_set fs_alpha_test_masks; - for (u32 alpha_test_bit = COMPILER_OPT_ENABLE_ALPHA_TEST_GE; - alpha_test_bit <= COMPILER_OPT_ENABLE_ALPHA_TEST_NE; - alpha_test_bit <<= 1) - { - for (const auto& mask : fs_masks) - { - fs_alpha_test_masks.insert(mask | alpha_test_bit); - } - } + for (u32 acc = a; acc < b; acc++) + { + func(acc << shift); + } + } - // VS - std::unordered_set vs_masks; - for (u32 vs_opt = COMPILER_OPT_VS_MIN; vs_opt <= COMPILER_OPT_VS_MAX; ++vs_opt) - { - vs_masks.insert(vs_opt); - } + std::vector get_interpreter_variants() + { + // Separable passes to fetch all possible variants + std::unordered_set fs_masks; + fs_masks.insert(0); + bitrange_foreach(COMPILER_OPT_FS_MIN, COMPILER_OPT_FS_MAX, [&](u32 fs_opt) + { + fs_masks.insert(fs_opt); + }); - // Merge all FS variants - fs_masks.merge(fs_alpha_test_masks); + // Now we add in the alpha testing variants for all fs variants. + // Only one alpha test type is usable at once + std::unordered_set fs_alpha_test_masks; + for (u32 alpha_test_bit = COMPILER_OPT_ENABLE_ALPHA_TEST_GE; + alpha_test_bit <= COMPILER_OPT_ENABLE_ALPHA_TEST_NE; + alpha_test_bit <<= 1) + { + for (const auto& mask : fs_masks) + { + fs_alpha_test_masks.insert(mask | alpha_test_bit); + } + } - // Prepare outputs - std::vector results; - for (const auto& vs_opt : vs_masks) - { - for (const auto& fs_opt : fs_masks) - { - results.push_back({ vs_opt, fs_opt }); - } - } + // VS + std::unordered_set vs_masks; + vs_masks.insert(0); + bitrange_foreach(COMPILER_OPT_VS_MIN, COMPILER_OPT_VS_MAX, [&](u32 vs_opt) + { + vs_masks.insert(vs_opt); + }); - return results; - } + // Merge all FS variants + fs_masks.merge(fs_alpha_test_masks); + + // Prepare outputs + std::vector results; + for (const auto& vs_opt : vs_masks) + { + for (const auto& fs_opt : fs_masks) + { + results.push_back({ vs_opt, fs_opt }); + } + } + + return results; + } } diff --git a/rpcs3/Emu/RSX/Program/ShaderInterpreter.h b/rpcs3/Emu/RSX/Program/ShaderInterpreter.h index d31da660b1..0090a5978e 100644 --- a/rpcs3/Emu/RSX/Program/ShaderInterpreter.h +++ b/rpcs3/Emu/RSX/Program/ShaderInterpreter.h @@ -6,30 +6,35 @@ namespace program_common { namespace interpreter { - enum compiler_option + enum compiler_option : u32 { + // FS Mix-N-Match COMPILER_OPT_ENABLE_TEXTURES = (1 << 0), COMPILER_OPT_ENABLE_DEPTH_EXPORT = (1 << 1), COMPILER_OPT_ENABLE_F32_EXPORT = (1 << 2), - COMPILER_OPT_ENABLE_ALPHA_TEST_GE = (1 << 3), - COMPILER_OPT_ENABLE_ALPHA_TEST_G = (1 << 4), - COMPILER_OPT_ENABLE_ALPHA_TEST_LE = (1 << 5), - COMPILER_OPT_ENABLE_ALPHA_TEST_L = (1 << 6), - COMPILER_OPT_ENABLE_ALPHA_TEST_EQ = (1 << 7), - COMPILER_OPT_ENABLE_ALPHA_TEST_NE = (1 << 8), - COMPILER_OPT_ENABLE_FLOW_CTRL = (1 << 9), - COMPILER_OPT_ENABLE_PACKING = (1 << 10), - COMPILER_OPT_ENABLE_KIL = (1 << 11), - COMPILER_OPT_ENABLE_STIPPLING = (1 << 12), - COMPILER_OPT_ENABLE_INSTANCING = (1 << 13), - COMPILER_OPT_ENABLE_VTX_TEXTURES = (1 << 14), + COMPILER_OPT_ENABLE_PACKING = (1 << 3), + COMPILER_OPT_ENABLE_KIL = (1 << 4), + COMPILER_OPT_ENABLE_STIPPLING = (1 << 5), + COMPILER_OPT_ENABLE_FLOW_CTRL = (1 << 6), + + // VS Mix-N-Match + COMPILER_OPT_ENABLE_INSTANCING = (1 << 7), + COMPILER_OPT_ENABLE_VTX_TEXTURES = (1 << 8), + + // Exclusive bits. Only one can be set at a time + COMPILER_OPT_ENABLE_ALPHA_TEST_GE = (1 << 9), + COMPILER_OPT_ENABLE_ALPHA_TEST_G = (1 << 10), + COMPILER_OPT_ENABLE_ALPHA_TEST_LE = (1 << 11), + COMPILER_OPT_ENABLE_ALPHA_TEST_L = (1 << 12), + COMPILER_OPT_ENABLE_ALPHA_TEST_EQ = (1 << 13), + COMPILER_OPT_ENABLE_ALPHA_TEST_NE = (1 << 14), // Meta - COMPILER_OPT_MAX = COMPILER_OPT_ENABLE_VTX_TEXTURES, - COMPILER_OPT_ALPHA_TEST_MASK = (0b111111 << COMPILER_OPT_ENABLE_ALPHA_TEST_GE), + COMPILER_OPT_MAX = COMPILER_OPT_ENABLE_ALPHA_TEST_NE, + COMPILER_OPT_ALPHA_TEST_MASK = (0b111111 << 9), // Bounds - COMPILER_OPT_FS_MAX = COMPILER_OPT_ENABLE_STIPPLING, + COMPILER_OPT_FS_MAX = COMPILER_OPT_ENABLE_FLOW_CTRL, COMPILER_OPT_FS_MIN = COMPILER_OPT_ENABLE_TEXTURES, COMPILER_OPT_VS_MAX = COMPILER_OPT_ENABLE_VTX_TEXTURES, COMPILER_OPT_VS_MIN = COMPILER_OPT_ENABLE_INSTANCING, diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index d08cac380e..9a8bc5a76c 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -171,6 +171,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index c6b10021cd..8534c79285 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1399,6 +1399,9 @@ Emu\GPU\RSX\Program\Assembler + + Emu\GPU\RSX\Program + Emu\Io