shader_cache: Only lock covered instructions.

This commit is contained in:
Markus Wick 2018-11-20 20:14:48 +01:00
parent b6d2c64f4d
commit cfbae58b2b
4 changed files with 24 additions and 8 deletions

View File

@ -84,6 +84,7 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)
} }
entries = program_result.second; entries = program_result.second;
shader_length = entries.shader_length;
if (program_type != Maxwell::ShaderProgram::Geometry) { if (program_type != Maxwell::ShaderProgram::Geometry) {
OGLShader shader; OGLShader shader;

View File

@ -30,7 +30,7 @@ public:
} }
std::size_t GetSizeInBytes() const override { std::size_t GetSizeInBytes() const override {
return GLShader::MAX_PROGRAM_CODE_LENGTH * sizeof(u64); return shader_length;
} }
// We do not have to flush this cache as things in it are never modified by us. // We do not have to flush this cache as things in it are never modified by us.
@ -82,6 +82,7 @@ private:
u32 max_vertices, const std::string& debug_name); u32 max_vertices, const std::string& debug_name);
VAddr addr; VAddr addr;
std::size_t shader_length;
Maxwell::ShaderProgram program_type; Maxwell::ShaderProgram program_type;
GLShader::ShaderSetup setup; GLShader::ShaderSetup setup;
GLShader::ShaderEntries entries; GLShader::ShaderEntries entries;

View File

@ -85,7 +85,8 @@ struct Subroutine {
class ControlFlowAnalyzer { class ControlFlowAnalyzer {
public: public:
ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix) ControlFlowAnalyzer(const ProgramCode& program_code, u32 main_offset, const std::string& suffix)
: program_code(program_code) { : program_code(program_code), shader_coverage_begin(main_offset),
shader_coverage_end(main_offset + 1) {
// Recursively finds all subroutines. // Recursively finds all subroutines.
const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix); const Subroutine& program_main = AddSubroutine(main_offset, PROGRAM_END, suffix);
@ -97,10 +98,16 @@ public:
return std::move(subroutines); return std::move(subroutines);
} }
std::size_t GetShaderLength() const {
return shader_coverage_end * sizeof(u64);
}
private: private:
const ProgramCode& program_code; const ProgramCode& program_code;
std::set<Subroutine> subroutines; std::set<Subroutine> subroutines;
std::map<std::pair<u32, u32>, ExitMethod> exit_method_map; std::map<std::pair<u32, u32>, ExitMethod> exit_method_map;
u32 shader_coverage_begin;
u32 shader_coverage_end;
/// Adds and analyzes a new subroutine if it is not added yet. /// Adds and analyzes a new subroutine if it is not added yet.
const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) { const Subroutine& AddSubroutine(u32 begin, u32 end, const std::string& suffix) {
@ -142,6 +149,9 @@ private:
return exit_method; return exit_method;
for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) { for (u32 offset = begin; offset != end && offset != PROGRAM_END; ++offset) {
shader_coverage_begin = std::min(shader_coverage_begin, offset);
shader_coverage_end = std::max(shader_coverage_end, offset + 1);
const Instruction instr = {program_code[offset]}; const Instruction instr = {program_code[offset]};
if (const auto opcode = OpCode::Decode(instr)) { if (const auto opcode = OpCode::Decode(instr)) {
switch (opcode->get().GetId()) { switch (opcode->get().GetId()) {
@ -951,9 +961,10 @@ private:
class GLSLGenerator { class GLSLGenerator {
public: public:
GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code, GLSLGenerator(const std::set<Subroutine>& subroutines, const ProgramCode& program_code,
u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix) u32 main_offset, Maxwell3D::Regs::ShaderStage stage, const std::string& suffix,
std::size_t shader_length)
: subroutines(subroutines), program_code(program_code), main_offset(main_offset), : subroutines(subroutines), program_code(program_code), main_offset(main_offset),
stage(stage), suffix(suffix) { stage(stage), suffix(suffix), shader_length(shader_length) {
std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header)); std::memcpy(&header, program_code.data(), sizeof(Tegra::Shader::Header));
local_memory_size = header.GetLocalMemorySize(); local_memory_size = header.GetLocalMemorySize();
regs.SetLocalMemory(local_memory_size); regs.SetLocalMemory(local_memory_size);
@ -966,7 +977,7 @@ public:
/// Returns entries in the shader that are useful for external functions /// Returns entries in the shader that are useful for external functions
ShaderEntries GetEntries() const { ShaderEntries GetEntries() const {
return {regs.GetConstBuffersDeclarations(), regs.GetSamplers()}; return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length};
} }
private: private:
@ -3827,6 +3838,7 @@ private:
Maxwell3D::Regs::ShaderStage stage; Maxwell3D::Regs::ShaderStage stage;
const std::string& suffix; const std::string& suffix;
u64 local_memory_size; u64 local_memory_size;
std::size_t shader_length;
ShaderWriter shader; ShaderWriter shader;
ShaderWriter declarations; ShaderWriter declarations;
@ -3845,9 +3857,10 @@ std::optional<ProgramResult> DecompileProgram(const ProgramCode& program_code, u
Maxwell3D::Regs::ShaderStage stage, Maxwell3D::Regs::ShaderStage stage,
const std::string& suffix) { const std::string& suffix) {
try { try {
const auto subroutines = ControlFlowAnalyzer analyzer(program_code, main_offset, suffix);
ControlFlowAnalyzer(program_code, main_offset, suffix).GetSubroutines(); const auto subroutines = analyzer.GetSubroutines();
GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix); GLSLGenerator generator(subroutines, program_code, main_offset, stage, suffix,
analyzer.GetShaderLength());
return ProgramResult{generator.GetShaderCode(), generator.GetEntries()}; return ProgramResult{generator.GetShaderCode(), generator.GetEntries()};
} catch (const DecompileFail& exception) { } catch (const DecompileFail& exception) {
LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what()); LOG_ERROR(HW_GPU, "Shader decompilation failed: {}", exception.what());

View File

@ -163,6 +163,7 @@ private:
struct ShaderEntries { struct ShaderEntries {
std::vector<ConstBufferEntry> const_buffer_entries; std::vector<ConstBufferEntry> const_buffer_entries;
std::vector<SamplerEntry> texture_samplers; std::vector<SamplerEntry> texture_samplers;
std::size_t shader_length;
}; };
using ProgramResult = std::pair<std::string, ShaderEntries>; using ProgramResult = std::pair<std::string, ShaderEntries>;