From fd8ceacef7cf8c831e3afc34de38ca6ca1ba5647 Mon Sep 17 00:00:00 2001 From: psucien Date: Sat, 15 Jun 2024 23:24:32 +0200 Subject: [PATCH] video_core: shaders hash switched to one from binary header --- src/core/libraries/gnmdriver/gnmdriver.cpp | 8 ++++---- src/video_core/amdgpu/liverpool.h | 17 ++++++++++++++++- .../renderer_vulkan/vk_graphics_pipeline.h | 2 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 11 +++++------ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index bf11904d..05ae882f 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -622,7 +622,6 @@ int PS4_SYSV_ABI sceGnmGetShaderStatus() { VAddr PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress() { LOG_TRACE(Lib_GnmDriver, "called"); - // Actual virtual buffer address is hardcoded in the driver to 0xff00'000 return tessellation_factors_ring_addr; } @@ -964,15 +963,16 @@ s32 PS4_SYSV_ABI sceGnmSetEmbeddedVsShader(u32* cmdbuf, u32 size, u32 shader_id, 0x4a0202c1u, // v_add_i32 v1, vcc, -1, v1 0x4a0000c1u, // v_add_i32 v0, vcc, -1, v0 0x7e020b01u, // v_cvt_f32_i32 v1, v1 - 0x7E000B00U, - 0x7e040280u, // v_cvt_f32_i32 v0, v0 + 0x7e000b00U, // v_cvt_f32_i32 v0, v0 + 0x7e040280u, // v_mov_b32 v2, 0 0x7e0602f2u, // v_mov_b32 v3, 1.0 0xf80008cfu, 0x03020001u, // exp pos0, v1, v0, v2, v3 done 0xf800020fu, 0x03030303u, // exp param0, v3, v3, v3, v3 0xbf810000u, // s_endpgm - // OrbShdr header + // Binary header 0x5362724fu, 0x07726468u, 0x00004047u, 0u, 0x47f8c29fu, 0x9b2da5cfu, 0xff7c5b7du, + // VS regs 0x00000017u, 0x0fe000f1u, 0u, 0x000c0000u, 4u, 0u, 4u, 0u, 7u, }; // clang-format on diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index dd717990..b4a71997 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -49,7 +49,9 @@ struct Liverpool { using UserData = std::array; struct BinaryInfo { - u8 signature[7]; + static constexpr u8 signature_ref[] = {0x4f, 0x72, 0x62, 0x53, 0x68, 0x64, 0x72}; // OrbShdr + + std::array signature; u8 version; u32 pssl_or_cg : 1; u32 cached : 1; @@ -65,6 +67,11 @@ struct Liverpool { u8 reserved3; u64 shader_hash; u32 crc32; + + bool Valid() const { + return shader_hash && crc32 && + (std::memcmp(signature.data(), signature_ref, sizeof(signature_ref)) == 0); + } }; struct ShaderProgram { @@ -134,6 +141,14 @@ struct Liverpool { } }; + template + static constexpr auto* GetBinaryInfo(const Shader& sh) { + const auto* code = sh.template Address(); + const auto* bininfo = std::bit_cast(code + (code[1] + 1) * 2); + ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header"); + return bininfo; + } + union PsInputControl { u32 raw; BitField<0, 5, u32> input_offset; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 4b38aa3d..cccd35e3 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -71,7 +71,7 @@ public: } [[nodiscard]] bool IsEmbeddedVs() const noexcept { - static constexpr size_t EmbeddedVsHash = 0x59c556606a027efd; + static constexpr size_t EmbeddedVsHash = 0x9b2da5cf47f8c29f; return key.stage_hashes[0] == EmbeddedVsHash; } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 139f7715..d8992e6e 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include #include "common/config.h" #include "common/io_file.h" #include "common/path_util.h" @@ -74,8 +73,8 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() { const ComputePipeline* PipelineCache::GetComputePipeline() { const auto& cs_pgm = liverpool->regs.cs_program; ASSERT(cs_pgm.Address() != nullptr); - const auto code = cs_pgm.Code(); - compute_key = XXH3_64bits(code.data(), code.size_bytes()); + const auto* bininfo = Liverpool::GetBinaryInfo(cs_pgm); + compute_key = bininfo->shader_hash; const auto [it, is_new] = compute_pipelines.try_emplace(compute_key); if (is_new) { it.value() = CreateComputePipeline(); @@ -147,8 +146,8 @@ void PipelineCache::RefreshGraphicsKey() { key.stage_hashes[i] = 0; continue; } - const auto code = pgm->Code(); - key.stage_hashes[i] = XXH3_64bits(code.data(), code.size_bytes()); + const auto* bininfo = Liverpool::GetBinaryInfo(*pgm); + key.stage_hashes[i] = bininfo->shader_hash; } } @@ -243,7 +242,7 @@ void PipelineCache::DumpShader(std::span code, u64 hash, Shader::Stag if (!std::filesystem::exists(dump_dir)) { std::filesystem::create_directories(dump_dir); } - const auto filename = fmt::format("{}_{:#X}.{}", stage, hash, ext); + const auto filename = fmt::format("{}_{:#018x}.{}", stage, hash, ext); const auto file = IOFile{dump_dir / filename, FileAccessMode::Write}; file.WriteSpan(code); }