shader: avoid recomputing hash for the same program
This commit is contained in:
parent
3cc460ab34
commit
d52ddd0ec4
3 changed files with 39 additions and 3 deletions
|
@ -451,6 +451,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
||||||
LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
|
LOG_ERROR(HW_GPU, "Invalid GS program offset %u", offset);
|
||||||
} else {
|
} else {
|
||||||
g_state.gs.program_code[offset] = value;
|
g_state.gs.program_code[offset] = value;
|
||||||
|
g_state.gs.MarkProgramCodeDirty();
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
break;
|
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);
|
LOG_ERROR(HW_GPU, "Invalid GS swizzle pattern offset %u", offset);
|
||||||
} else {
|
} else {
|
||||||
g_state.gs.swizzle_data[offset] = value;
|
g_state.gs.swizzle_data[offset] = value;
|
||||||
|
g_state.gs.MarkSwizzleDataDirty();
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -518,8 +520,10 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
|
||||||
LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
|
LOG_ERROR(HW_GPU, "Invalid VS program offset %u", offset);
|
||||||
} else {
|
} else {
|
||||||
g_state.vs.program_code[offset] = value;
|
g_state.vs.program_code[offset] = value;
|
||||||
|
g_state.vs.MarkProgramCodeDirty();
|
||||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||||
g_state.gs.program_code[offset] = value;
|
g_state.gs.program_code[offset] = value;
|
||||||
|
g_state.gs.MarkProgramCodeDirty();
|
||||||
}
|
}
|
||||||
offset++;
|
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);
|
LOG_ERROR(HW_GPU, "Invalid VS swizzle pattern offset %u", offset);
|
||||||
} else {
|
} else {
|
||||||
g_state.vs.swizzle_data[offset] = value;
|
g_state.vs.swizzle_data[offset] = value;
|
||||||
|
g_state.vs.MarkSwizzleDataDirty();
|
||||||
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
if (!g_state.regs.pipeline.gs_unit_exclusive_configuration) {
|
||||||
g_state.gs.swizzle_data[offset] = value;
|
g_state.gs.swizzle_data[offset] = value;
|
||||||
|
g_state.gs.MarkSwizzleDataDirty();
|
||||||
}
|
}
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/hash.h"
|
||||||
#include "common/vector_math.h"
|
#include "common/vector_math.h"
|
||||||
#include "video_core/pica_types.h"
|
#include "video_core/pica_types.h"
|
||||||
#include "video_core/regs_rasterizer.h"
|
#include "video_core/regs_rasterizer.h"
|
||||||
|
@ -206,6 +207,36 @@ struct ShaderSetup {
|
||||||
/// Used by the JIT, points to a compiled shader object.
|
/// Used by the JIT, points to a compiled shader object.
|
||||||
const void* cached_shader = nullptr;
|
const void* cached_shader = nullptr;
|
||||||
} engine_data;
|
} 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 {
|
class ShaderEngine {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/hash.h"
|
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "video_core/shader/shader.h"
|
#include "video_core/shader/shader.h"
|
||||||
#include "video_core/shader/shader_jit_x64.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);
|
ASSERT(entry_point < MAX_PROGRAM_CODE_LENGTH);
|
||||||
setup.engine_data.entry_point = entry_point;
|
setup.engine_data.entry_point = entry_point;
|
||||||
|
|
||||||
u64 code_hash = Common::ComputeHash64(&setup.program_code, sizeof(setup.program_code));
|
u64 code_hash = setup.GetProgramCodeHash();
|
||||||
u64 swizzle_hash = Common::ComputeHash64(&setup.swizzle_data, sizeof(setup.swizzle_data));
|
u64 swizzle_hash = setup.GetSwizzleDataHash();
|
||||||
|
|
||||||
u64 cache_key = code_hash ^ swizzle_hash;
|
u64 cache_key = code_hash ^ swizzle_hash;
|
||||||
auto iter = cache.find(cache_key);
|
auto iter = cache.find(cache_key);
|
||||||
|
|
Loading…
Reference in a new issue