shader: avoid recomputing hash for the same program

This commit is contained in:
wwylele 2018-04-17 09:47:59 +03:00
parent 3cc460ab34
commit d52ddd0ec4
3 changed files with 39 additions and 3 deletions

View file

@ -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++;
}

View file

@ -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 {

View file

@ -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);