diff options
| author | 2023-08-03 12:18:35 +0100 | |
|---|---|---|
| committer | 2023-08-03 15:30:27 +0100 | |
| commit | dfb7fc8293a528d6c8cc2abef7fac5a6a7bf2883 (patch) | |
| tree | faf1c9bce2d7159b0f9b7bb3cdd08be7f47f7847 /src/video_core/shader_environment.cpp | |
| parent | Merge pull request #11202 from abouvier/vulkan-config (diff) | |
| download | yuzu-dfb7fc8293a528d6c8cc2abef7fac5a6a7bf2883.tar.gz yuzu-dfb7fc8293a528d6c8cc2abef7fac5a6a7bf2883.tar.xz yuzu-dfb7fc8293a528d6c8cc2abef7fac5a6a7bf2883.zip | |
Fix shader dumps with nvdisasm
skip fragment shaders when rasterizer is disabled
initialize env_ptrs
Diffstat (limited to 'src/video_core/shader_environment.cpp')
| -rw-r--r-- | src/video_core/shader_environment.cpp | 31 |
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 | ||
| 105 | static void DumpImpl(u64 hash, const u64* code, u32 read_highest, u32 read_lowest, | 105 | static 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 | ||
| 200 | void GenericEnvironment::Dump(u64 hash) { | 206 | void 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 | ||
| 204 | void GenericEnvironment::Serialize(std::ofstream& file) const { | 210 | void GenericEnvironment::Serialize(std::ofstream& file) const { |
| @@ -282,6 +288,7 @@ std::optional<u64> GenericEnvironment::TryFindSize() { | |||
| 282 | Tegra::Texture::TICEntry GenericEnvironment::ReadTextureInfo(GPUVAddr tic_addr, u32 tic_limit, | 288 | Tegra::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 | ||
| 512 | void FileEnvironment::Dump(u64 hash) { | 519 | void 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 | ||
| 516 | u64 FileEnvironment::ReadInstruction(u32 address) { | 523 | u64 FileEnvironment::ReadInstruction(u32 address) { |