mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
switch to using single codegenerator
This commit is contained in:
parent
539ecd211f
commit
99369a67e1
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <vector>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
@ -17,7 +18,6 @@
|
|||||||
#include "shader_recompiler/params.h"
|
#include "shader_recompiler/params.h"
|
||||||
#include "shader_recompiler/runtime_info.h"
|
#include "shader_recompiler/runtime_info.h"
|
||||||
#include "video_core/amdgpu/resource.h"
|
#include "video_core/amdgpu/resource.h"
|
||||||
#include "xbyak/xbyak.h"
|
|
||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
@ -204,9 +204,6 @@ struct Info {
|
|||||||
bool has_readconst{};
|
bool has_readconst{};
|
||||||
u8 mrt_mask{0u};
|
u8 mrt_mask{0u};
|
||||||
|
|
||||||
// just for logging, TODO delete
|
|
||||||
size_t perm_idx;
|
|
||||||
|
|
||||||
explicit Info(Stage stage_, ShaderParams params)
|
explicit Info(Stage stage_, ShaderParams params)
|
||||||
: stage{stage_}, pgm_hash{params.hash}, pgm_base{params.Base()},
|
: stage{stage_}, pgm_hash{params.hash}, pgm_base{params.Base()},
|
||||||
user_data{params.user_data} {}
|
user_data{params.user_data} {}
|
||||||
@ -263,9 +260,8 @@ struct Info {
|
|||||||
ASSERT(user_data.size() <= NumUserDataRegs);
|
ASSERT(user_data.size() <= NumUserDataRegs);
|
||||||
std::memcpy(flattened_ud_buf.data(), user_data.data(), user_data.size_bytes());
|
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
|
// 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 (srt_info.walker_func) {
|
||||||
if (pfn) {
|
srt_info.walker_func(user_data.data(), flattened_ud_buf.data());
|
||||||
pfn(user_data.data(), flattened_ud_buf.data());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "common/singleton.h"
|
|
||||||
#include "shader_recompiler/info.h"
|
#include "shader_recompiler/info.h"
|
||||||
#include "shader_recompiler/ir/breadth_first_search.h"
|
#include "shader_recompiler/ir/breadth_first_search.h"
|
||||||
#include "shader_recompiler/ir/opcodes.h"
|
#include "shader_recompiler/ir/opcodes.h"
|
||||||
@ -24,7 +23,9 @@
|
|||||||
|
|
||||||
using namespace Xbyak::util;
|
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) {
|
static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t codesize) {
|
||||||
#ifdef ARCH_X86_64
|
#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)) {
|
if (!std::filesystem::exists(dump_dir)) {
|
||||||
std::filesystem::create_directories(dump_dir);
|
std::filesystem::create_directories(dump_dir);
|
||||||
}
|
}
|
||||||
const auto filename =
|
const auto filename = fmt::format("{}_{:#018x}.srtprogram.txt", info.stage, info.pgm_hash);
|
||||||
fmt::format("{}_{:#018x}_{}.srtprogram.txt", info.stage, info.pgm_hash, info.perm_idx);
|
|
||||||
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write, FileType::TextFile};
|
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write, FileType::TextFile};
|
||||||
|
|
||||||
u64 address = reinterpret_cast<u64>(code);
|
u64 address = reinterpret_cast<u64>(code);
|
||||||
@ -54,12 +54,6 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
class SrtCodegen : public Xbyak::CodeGenerator {
|
|
||||||
public:
|
|
||||||
SrtCodegen() : CodeGenerator(1_MB) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
using namespace Shader;
|
using namespace Shader;
|
||||||
|
|
||||||
struct PassInfo {
|
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) {
|
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()) {
|
if (info.srt_info.srt_reservations.empty() && pass_info.srt_roots.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.srt_info.walker_func = c.getCurr<PFN_SrtWalker>();
|
||||||
|
|
||||||
pass_info.dst_off_dw = NumUserDataRegs;
|
pass_info.dst_off_dw = NumUserDataRegs;
|
||||||
|
|
||||||
// Special case for V# step rate buffers in fetch shader
|
// 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.ret();
|
||||||
c.ready();
|
c.ready();
|
||||||
|
|
||||||
size_t codesize = c.getSize();
|
|
||||||
info.srt_info.walker = SmallCodeArray(c.getCode(), codesize);
|
|
||||||
|
|
||||||
if (Config::dumpShaders()) {
|
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;
|
info.srt_info.flattened_bufsize_dw = pass_info.dst_off_dw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,69 +3,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#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/set.hpp>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include "common/alignment.h"
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "xbyak/xbyak.h"
|
|
||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
using PFN_SrtWalker = void PS4_SYSV_ABI (*)(const u32* /*user_data*/, u32* /*flat_dst*/);
|
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 {
|
struct PersistentSrtInfo {
|
||||||
// Special case when fetch shader uses step rates.
|
// Special case when fetch shader uses step rates.
|
||||||
struct SrtSharpReservation {
|
struct SrtSharpReservation {
|
||||||
@ -74,7 +19,7 @@ struct PersistentSrtInfo {
|
|||||||
u32 num_dwords;
|
u32 num_dwords;
|
||||||
};
|
};
|
||||||
|
|
||||||
SmallCodeArray walker;
|
PFN_SrtWalker walker_func{};
|
||||||
boost::container::small_vector<SrtSharpReservation, 2> srt_reservations;
|
boost::container::small_vector<SrtSharpReservation, 2> srt_reservations;
|
||||||
u32 flattened_bufsize_dw = 16; // NumUserDataRegs
|
u32 flattened_bufsize_dw = 16; // NumUserDataRegs
|
||||||
|
|
||||||
|
@ -396,7 +396,6 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info,
|
|||||||
perm_idx != 0 ? "(permutation)" : "");
|
perm_idx != 0 ? "(permutation)" : "");
|
||||||
DumpShader(code, info.pgm_hash, info.stage, perm_idx, "bin");
|
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 ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile);
|
||||||
const auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding);
|
const auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding);
|
||||||
DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv");
|
DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv");
|
||||||
|
Loading…
Reference in New Issue
Block a user