switch to using single codegenerator

This commit is contained in:
Frodo Baggins 2024-10-30 21:36:14 -07:00
parent 539ecd211f
commit 99369a67e1
4 changed files with 13 additions and 81 deletions

View File

@ -4,6 +4,7 @@
#include <algorithm>
#include <span>
#include <vector>
#include <boost/container/small_vector.hpp>
#include <boost/container/static_vector.hpp>
#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<PFN_SrtWalker>();
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());
}
}
};

View File

@ -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<u64>(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<SrtCodegen>::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<PFN_SrtWalker>();
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<const u8*>(info.srt_info.walker_func);
DumpSrtProgram(info, reinterpret_cast<const u8*>(info.srt_info.walker_func), codesize);
}
c.reset();
info.srt_info.flattened_bufsize_dw = pass_info.dst_off_dw;
}

View File

@ -3,69 +3,14 @@
#pragma once
#include <vector>
#include <boost/align/aligned_allocator.hpp>
#include <boost/align/aligned_delete.hpp>
#include <boost/container/map.hpp>
#include <boost/container/set.hpp>
#include <boost/container/small_vector.hpp>
#include <memory>
#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<u8*>(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<u8*>(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 <class F>
F getCode() const {
return reinterpret_cast<F>(codebuf.get());
}
private:
using aligned_unique_ptr = std::unique_ptr<u8, boost::alignment::aligned_delete>;
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<SrtSharpReservation, 2> srt_reservations;
u32 flattened_bufsize_dw = 16; // NumUserDataRegs

View File

@ -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");