diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 022d8dee3..8612a758f 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -451,6 +451,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset); } else { g_state.gs.program_code[offset] = value; + g_state.gs.MarkProgramCodeDirty(); offset++; } break; @@ -469,6 +470,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset); } else { g_state.gs.swizzle_data[offset] = value; + g_state.gs.MarkSwizzleDataDirty(); offset++; } break; @@ -518,8 +520,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset); } else { g_state.vs.program_code[offset] = value; + g_state.vs.MarkProgramCodeDirty(); if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { g_state.gs.program_code[offset] = value; + g_state.gs.MarkProgramCodeDirty(); } offset++; } @@ -539,8 +543,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset); } else { g_state.vs.swizzle_data[offset] = value; + g_state.vs.MarkSwizzleDataDirty(); if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) { g_state.gs.swizzle_data[offset] = value; + g_state.gs.MarkSwizzleDataDirty(); } offset++; } diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 8b212100c..86e902a1c 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -12,6 +12,7 @@ #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/hash.h" #include "common/vector_math.h" #include "video_core/pica_types.h" #include "video_core/regs_rasterizer.h" @@ -206,6 +207,36 @@ struct ShaderSetup { /// Used by the JIT, points to a compiled shader object. const void* cached_shader = nullptr; } engine_data; + + void MarkProgramCodeDirty() { + program_code_hash_dirty = true; + } + + void MarkSwizzleDataDirty() { + swizzle_data_hash_dirty = true; + } + + u64 GetProgramCodeHash() { + if (program_code_hash_dirty) { + program_code_hash = Common::ComputeHash64(&program_code, sizeof(program_code)); + program_code_hash_dirty = false; + } + return program_code_hash; + } + + u64 GetSwizzleDataHash() { + if (swizzle_data_hash_dirty) { + swizzle_data_hash = Common::ComputeHash64(&swizzle_data, sizeof(swizzle_data)); + swizzle_data_hash_dirty = false; + } + return swizzle_data_hash; + } + +private: + bool program_code_hash_dirty = true; + bool swizzle_data_hash_dirty = true; + u64 program_code_hash = 0xDEADC0DE; + u64 swizzle_data_hash = 0xDEADC0DE; }; class ShaderEngine { diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index 73c21871c..696fe11da 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/hash.h" #include "common/microprofile.h" #include "video_core/shader/shader.h" #include "video_core/shader/shader_jit_x64.h" @@ -18,8 +17,8 @@ void JitX64Engine::SetupBatch(ShaderSetup& setup, unsigned int entry_point) { ASSERT(entry_point < MAX_PROGRAM_CODE_LENGTH); setup.engine_data.entry_point = entry_point; - u64 code_hash = Common::ComputeHash64(&setup.program_code, sizeof(setup.program_code)); - u64 swizzle_hash = Common::ComputeHash64(&setup.swizzle_data, sizeof(setup.swizzle_data)); + u64 code_hash = setup.GetProgramCodeHash(); + u64 swizzle_hash = setup.GetSwizzleDataHash(); u64 cache_key = code_hash ^ swizzle_hash; auto iter = cache.find(cache_key);