1
0
Fork 0
forked from suyu/suyu

gl_shader_gen: Use a std::vector to represent program code instead of std::array

While convenient as a std::array, it's also quite a large set of data as
well (32KB). It being an array also means data cannot be std::moved. Any
situation where the code is being set or relocated means that a full
copy of that 32KB data must be done.

If we use a std::vector we do need to allocate on the heap, however, it
does allow us to std::move the data we have within the std::vector into
another std::vector instance, eliminating the need to always copy the
program data (as std::move in this case would just transfer the pointers
and bare necessities over to the new vector instance).
This commit is contained in:
Lioncash 2018-08-22 15:43:52 -04:00
parent d1b1c42c07
commit 1fd979f50a
2 changed files with 16 additions and 11 deletions

View file

@ -179,7 +179,7 @@ static GLShader::ProgramCode GetShaderProgramCode(Maxwell::ShaderProgram program
auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
// Fetch program code from memory // Fetch program code from memory
GLShader::ProgramCode program_code; GLShader::ProgramCode program_code(GLShader::MAX_PROGRAM_CODE_LENGTH);
auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)]; auto& shader_config = gpu.regs.shader_config[static_cast<size_t>(program)];
const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset};
const boost::optional<VAddr> cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; const boost::optional<VAddr> cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)};

View file

@ -9,14 +9,14 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/functional/hash.hpp>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/hash.h" #include "common/hash.h"
namespace GLShader { namespace GLShader {
constexpr size_t MAX_PROGRAM_CODE_LENGTH{0x1000}; constexpr size_t MAX_PROGRAM_CODE_LENGTH{0x1000};
using ProgramCode = std::vector<u64>;
using ProgramCode = std::array<u64, MAX_PROGRAM_CODE_LENGTH>;
class ConstBufferEntry { class ConstBufferEntry {
using Maxwell = Tegra::Engines::Maxwell3D::Regs; using Maxwell = Tegra::Engines::Maxwell3D::Regs;
@ -115,8 +115,8 @@ struct ShaderEntries {
using ProgramResult = std::pair<std::string, ShaderEntries>; using ProgramResult = std::pair<std::string, ShaderEntries>;
struct ShaderSetup { struct ShaderSetup {
ShaderSetup(const ProgramCode& program_code) { ShaderSetup(ProgramCode program_code) {
program.code = program_code; program.code = std::move(program_code);
} }
struct { struct {
@ -135,8 +135,8 @@ struct ShaderSetup {
} }
/// Used in scenarios where we have a dual vertex shaders /// Used in scenarios where we have a dual vertex shaders
void SetProgramB(const ProgramCode& program_b) { void SetProgramB(ProgramCode program_b) {
program.code_b = program_b; program.code_b = std::move(program_b);
has_program_b = true; has_program_b = true;
} }
@ -146,13 +146,18 @@ struct ShaderSetup {
private: private:
u64 GetNewHash() const { u64 GetNewHash() const {
size_t hash = 0;
const u64 hash_a = Common::ComputeHash64(program.code.data(), program.code.size());
boost::hash_combine(hash, hash_a);
if (has_program_b) { if (has_program_b) {
// Compute hash over dual shader programs // Compute hash over dual shader programs
return Common::ComputeHash64(&program, sizeof(program)); const u64 hash_b = Common::ComputeHash64(program.code_b.data(), program.code_b.size());
} else { boost::hash_combine(hash, hash_b);
// Compute hash over a single shader program
return Common::ComputeHash64(&program.code, program.code.size());
} }
return hash;
} }
u64 program_code_hash{}; u64 program_code_hash{};