From 99369a67e1ad4d9c06c1203a315d6ea216e80554 Mon Sep 17 00:00:00 2001 From: Frodo Baggins Date: Wed, 30 Oct 2024 21:36:14 -0700 Subject: [PATCH] switch to using single codegenerator --- src/shader_recompiler/info.h | 10 +--- .../passes/flatten_extended_userdata_pass.cpp | 26 +++------ src/shader_recompiler/ir/passes/srt.h | 57 +------------------ .../renderer_vulkan/vk_pipeline_cache.cpp | 1 - 4 files changed, 13 insertions(+), 81 deletions(-) diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 610090da0..b69863f4f 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include "common/assert.h" @@ -17,7 +18,6 @@ #include "shader_recompiler/params.h" #include "shader_recompiler/runtime_info.h" #include "video_core/amdgpu/resource.h" -#include "xbyak/xbyak.h" namespace Shader { @@ -204,9 +204,6 @@ struct Info { bool has_readconst{}; u8 mrt_mask{0u}; - // just for logging, TODO delete - size_t perm_idx; - explicit Info(Stage stage_, ShaderParams params) : stage{stage_}, pgm_hash{params.hash}, pgm_base{params.Base()}, user_data{params.user_data} {} @@ -263,9 +260,8 @@ struct Info { ASSERT(user_data.size() <= NumUserDataRegs); std::memcpy(flattened_ud_buf.data(), user_data.data(), user_data.size_bytes()); // Run the JIT program to walk the SRT and write the leaves to a flat buffer - PFN_SrtWalker pfn = srt_info.walker.getCode(); - if (pfn) { - pfn(user_data.data(), flattened_ud_buf.data()); + if (srt_info.walker_func) { + srt_info.walker_func(user_data.data(), flattened_ud_buf.data()); } } }; diff --git a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp index edea69565..6292edfd8 100644 --- a/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp +++ b/src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp @@ -10,7 +10,6 @@ #include "common/io_file.h" #include "common/logging/log.h" #include "common/path_util.h" -#include "common/singleton.h" #include "shader_recompiler/info.h" #include "shader_recompiler/ir/breadth_first_search.h" #include "shader_recompiler/ir/opcodes.h" @@ -24,7 +23,9 @@ using namespace Xbyak::util; -// TODO make sure no problems with identity and Insts being used in maps +static Xbyak::CodeGenerator g_srt_codegen(32_MB); + +namespace { static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t codesize) { #ifdef ARCH_X86_64 @@ -34,8 +35,7 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code if (!std::filesystem::exists(dump_dir)) { std::filesystem::create_directories(dump_dir); } - const auto filename = - fmt::format("{}_{:#018x}_{}.srtprogram.txt", info.stage, info.pgm_hash, info.perm_idx); + const auto filename = fmt::format("{}_{:#018x}.srtprogram.txt", info.stage, info.pgm_hash); const auto file = IOFile{dump_dir / filename, FileAccessMode::Write, FileType::TextFile}; u64 address = reinterpret_cast(code); @@ -54,12 +54,6 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code #endif } -namespace { -class SrtCodegen : public Xbyak::CodeGenerator { -public: - SrtCodegen() : CodeGenerator(1_MB) {} -}; - using namespace Shader; struct PassInfo { @@ -141,12 +135,14 @@ static void VisitPointer(u32 off_dw, IR::Inst* subtree, PassInfo& pass_info, } static void GenerateSrtProgram(Info& info, PassInfo& pass_info) { - Xbyak::CodeGenerator& c = *Common::Singleton::Instance(); + Xbyak::CodeGenerator& c = g_srt_codegen; if (info.srt_info.srt_reservations.empty() && pass_info.srt_roots.empty()) { return; } + info.srt_info.walker_func = c.getCurr(); + pass_info.dst_off_dw = NumUserDataRegs; // Special case for V# step rate buffers in fetch shader @@ -174,15 +170,11 @@ static void GenerateSrtProgram(Info& info, PassInfo& pass_info) { c.ret(); c.ready(); - size_t codesize = c.getSize(); - info.srt_info.walker = SmallCodeArray(c.getCode(), codesize); - if (Config::dumpShaders()) { - DumpSrtProgram(info, c.getCode(), codesize); + size_t codesize = c.getCurr() - reinterpret_cast(info.srt_info.walker_func); + DumpSrtProgram(info, reinterpret_cast(info.srt_info.walker_func), codesize); } - c.reset(); - info.srt_info.flattened_bufsize_dw = pass_info.dst_off_dw; } diff --git a/src/shader_recompiler/ir/passes/srt.h b/src/shader_recompiler/ir/passes/srt.h index 95e8902a5..0ddc15ea6 100644 --- a/src/shader_recompiler/ir/passes/srt.h +++ b/src/shader_recompiler/ir/passes/srt.h @@ -3,69 +3,14 @@ #pragma once -#include -#include -#include -#include #include #include - -#include -#include "common/alignment.h" -#include "common/assert.h" #include "common/types.h" -#include "xbyak/xbyak.h" namespace Shader { using PFN_SrtWalker = void PS4_SYSV_ABI (*)(const u32* /*user_data*/, u32* /*flat_dst*/); -// Utility for copying a simple relocatable function from a Xbyak code generator to manage memory -// separately -class SmallCodeArray { -public: - SmallCodeArray() : bufsize(0), codebuf(nullptr) {} - SmallCodeArray& operator=(SmallCodeArray&& other) = default; - SmallCodeArray(SmallCodeArray&& other) = default; - - SmallCodeArray& operator=(const SmallCodeArray& other) { - *this = SmallCodeArray(reinterpret_cast(codebuf.get()), bufsize); - return *this; - } - SmallCodeArray(const SmallCodeArray& other) { - *this = other; - }; - - SmallCodeArray(const u8* code, size_t codesize) : SmallCodeArray() { - size_t pagesize = Xbyak::inner::getPageSize(); - bufsize = Common::AlignUp(codesize, pagesize); - if (bufsize > 0) { - auto fn = reinterpret_cast(boost::alignment::aligned_alloc(pagesize, bufsize)); - ASSERT(fn); - codebuf = aligned_unique_ptr(fn); - memcpy(codebuf.get(), code, codesize); - Xbyak::CodeArray::protect(codebuf.get(), bufsize, Xbyak::CodeArray::PROTECT_RE); - } - } - - ~SmallCodeArray() { - if (bufsize > 0) { - Xbyak::CodeArray::protect(codebuf.get(), bufsize, Xbyak::CodeArray::PROTECT_RW); - } - } - - template - F getCode() const { - return reinterpret_cast(codebuf.get()); - } - -private: - using aligned_unique_ptr = std::unique_ptr; - - size_t bufsize; - aligned_unique_ptr codebuf; -}; - struct PersistentSrtInfo { // Special case when fetch shader uses step rates. struct SrtSharpReservation { @@ -74,7 +19,7 @@ struct PersistentSrtInfo { u32 num_dwords; }; - SmallCodeArray walker; + PFN_SrtWalker walker_func{}; boost::container::small_vector srt_reservations; u32 flattened_bufsize_dw = 16; // NumUserDataRegs diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index adeac3f44..c368f2101 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -396,7 +396,6 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, perm_idx != 0 ? "(permutation)" : ""); DumpShader(code, info.pgm_hash, info.stage, perm_idx, "bin"); - info.perm_idx = perm_idx; const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile); const auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv");