summaryrefslogtreecommitdiff
path: root/src/video_core/shader_environment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader_environment.cpp')
-rw-r--r--src/video_core/shader_environment.cpp31
1 files changed, 19 insertions, 12 deletions
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index c7cb56243..4edbe5700 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -102,7 +102,8 @@ static std::string_view StageToPrefix(Shader::Stage stage) {
102 } 102 }
103} 103}
104 104
105static void DumpImpl(u64 hash, const u64* code, u32 read_highest, u32 read_lowest, 105static void DumpImpl(u64 pipeline_hash, u64 shader_hash, std::span<const u64> code,
106 [[maybe_unused]] u32 read_highest, [[maybe_unused]] u32 read_lowest,
106 u32 initial_offset, Shader::Stage stage) { 107 u32 initial_offset, Shader::Stage stage) {
107 const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)}; 108 const auto shader_dir{Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)};
108 const auto base_dir{shader_dir / "shaders"}; 109 const auto base_dir{shader_dir / "shaders"};
@@ -111,13 +112,18 @@ static void DumpImpl(u64 hash, const u64* code, u32 read_highest, u32 read_lowes
111 return; 112 return;
112 } 113 }
113 const auto prefix = StageToPrefix(stage); 114 const auto prefix = StageToPrefix(stage);
114 const auto name{base_dir / fmt::format("{}{:016x}.ash", prefix, hash)}; 115 const auto name{base_dir /
115 const size_t real_size = read_highest - read_lowest + initial_offset; 116 fmt::format("{:016x}_{}_{:016x}.ash", pipeline_hash, prefix, shader_hash)};
116 const size_t padding_needed = ((32 - (real_size % 32)) % 32);
117 std::fstream shader_file(name, std::ios::out | std::ios::binary); 117 std::fstream shader_file(name, std::ios::out | std::ios::binary);
118 ASSERT(initial_offset % sizeof(u64) == 0);
118 const size_t jump_index = initial_offset / sizeof(u64); 119 const size_t jump_index = initial_offset / sizeof(u64);
119 shader_file.write(reinterpret_cast<const char*>(code + jump_index), real_size); 120 const size_t code_size = code.size_bytes() - initial_offset;
120 for (size_t i = 0; i < padding_needed; i++) { 121 shader_file.write(reinterpret_cast<const char*>(&code[jump_index]), code_size);
122
123 // + 1 instruction, due to the fact that we skip the final self branch instruction in the code,
124 // but we need to consider it for padding, otherwise nvdisasm rages.
125 const size_t padding_needed = (32 - ((code_size + INST_SIZE) % 32)) % 32;
126 for (size_t i = 0; i < INST_SIZE + padding_needed; i++) {
121 shader_file.put(0); 127 shader_file.put(0);
122 } 128 }
123} 129}
@@ -197,8 +203,8 @@ u64 GenericEnvironment::CalculateHash() const {
197 return Common::CityHash64(data.get(), size); 203 return Common::CityHash64(data.get(), size);
198} 204}
199 205
200void GenericEnvironment::Dump(u64 hash) { 206void GenericEnvironment::Dump(u64 pipeline_hash, u64 shader_hash) {
201 DumpImpl(hash, code.data(), read_highest, read_lowest, initial_offset, stage); 207 DumpImpl(pipeline_hash, shader_hash, code, read_highest, read_lowest, initial_offset, stage);
202} 208}
203 209
204void GenericEnvironment::Serialize(std::ofstream& file) const { 210void GenericEnvironment::Serialize(std::ofstream& file) const {
@@ -282,6 +288,7 @@ std::optional<u64> GenericEnvironment::TryFindSize() {
282Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit, 288Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit,
283 bool via_header_index, u32 raw) { 289 bool via_header_index, u32 raw) {
284 const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)}; 290 const auto handle{Tegra::Texture::TexturePair(raw, via_header_index)};
291 ASSERT(handle.first <= tic_limit);
285 const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)}; 292 const GPUVAddr descriptor_addr{tic_addr + handle.first * sizeof(Tegra::Texture::TICEntry)};
286 Tegra::Texture::TICEntry entry; 293 Tegra::Texture::TICEntry entry;
287 gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry)); 294 gpu_memory->ReadBlock(descriptor_addr, &entry, sizeof(entry));
@@ -465,8 +472,8 @@ void FileEnvironment::Deserialize(std::ifstream& file) {
465 .read(reinterpret_cast<char*>(&read_highest), sizeof(read_highest)) 472 .read(reinterpret_cast<char*>(&read_highest), sizeof(read_highest))
466 .read(reinterpret_cast<char*>(&viewport_transform_state), sizeof(viewport_transform_state)) 473 .read(reinterpret_cast<char*>(&viewport_transform_state), sizeof(viewport_transform_state))
467 .read(reinterpret_cast<char*>(&stage), sizeof(stage)); 474 .read(reinterpret_cast<char*>(&stage), sizeof(stage));
468 code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); 475 code.resize(Common::DivCeil(code_size, sizeof(u64)));
469 file.read(reinterpret_cast<char*>(code.get()), code_size); 476 file.read(reinterpret_cast<char*>(code.data()), code_size);
470 for (size_t i = 0; i < num_texture_types; ++i) { 477 for (size_t i = 0; i < num_texture_types; ++i) {
471 u32 key; 478 u32 key;
472 Shader::TextureType type; 479 Shader::TextureType type;
@@ -509,8 +516,8 @@ void FileEnvironment::Deserialize(std::ifstream& file) {
509 is_propietary_driver = texture_bound == 2; 516 is_propietary_driver = texture_bound == 2;
510} 517}
511 518
512void FileEnvironment::Dump(u64 hash) { 519void FileEnvironment::Dump(u64 pipeline_hash, u64 shader_hash) {
513 DumpImpl(hash, code.get(), read_highest, read_lowest, initial_offset, stage); 520 DumpImpl(pipeline_hash, shader_hash, code, read_highest, read_lowest, initial_offset, stage);
514} 521}
515 522
516u64 FileEnvironment::ReadInstruction(u32 address) { 523u64 FileEnvironment::ReadInstruction(u32 address) {