diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.cpp b/rpcs3/Emu/RSX/Common/ProgramStateCache.cpp index 32b2ebb2d8..d98ef92d2b 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.cpp +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.cpp @@ -3,14 +3,14 @@ using namespace program_hash_util; -size_t vertex_program_hash::operator()(const std::vector &program) const +size_t vertex_program_hash::operator()(const RSXVertexProgram &program) const { // 64-bit Fowler/Noll/Vo FNV-1a hash code size_t hash = 0xCBF29CE484222325ULL; - const qword *instbuffer = (const qword*)program.data(); + const qword *instbuffer = (const qword*)program.data.data(); size_t instIndex = 0; bool end = false; - for (unsigned i = 0; i < program.size() / 4; i++) + for (unsigned i = 0; i < program.data.size() / 4; i++) { const qword inst = instbuffer[instIndex]; hash ^= inst.dword[0]; @@ -22,13 +22,17 @@ size_t vertex_program_hash::operator()(const std::vector &program) const return hash; } -bool vertex_program_compare::operator()(const std::vector &binary1, const std::vector &binary2) const +bool vertex_program_compare::operator()(const RSXVertexProgram &binary1, const RSXVertexProgram &binary2) const { - if (binary1.size() != binary2.size()) return false; - const qword *instBuffer1 = (const qword*)binary1.data(); - const qword *instBuffer2 = (const qword*)binary2.data(); + if (binary1.output_mask != binary2.output_mask) + return false; + if (binary1.rsx_vertex_inputs != binary2.rsx_vertex_inputs) + return false; + if (binary1.data.size() != binary2.data.size()) return false; + const qword *instBuffer1 = (const qword*)binary1.data.data(); + const qword *instBuffer2 = (const qword*)binary2.data.data(); size_t instIndex = 0; - for (unsigned i = 0; i < binary1.size() / 4; i++) + for (unsigned i = 0; i < binary1.data.size() / 4; i++) { const qword& inst1 = instBuffer1[instIndex]; const qword& inst2 = instBuffer2[instIndex]; diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index a2cddff089..eef6eecb3d 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -23,12 +23,12 @@ namespace program_hash_util struct vertex_program_hash { - size_t operator()(const std::vector &program) const; + size_t operator()(const RSXVertexProgram &program) const; }; struct vertex_program_compare { - bool operator()(const std::vector &binary1, const std::vector &binary2) const; + bool operator()(const RSXVertexProgram &binary1, const RSXVertexProgram &binary2) const; }; struct fragment_program_utils @@ -75,7 +75,7 @@ class program_state_cache using vertex_program_type = typename backend_traits::vertex_program_type; using fragment_program_type = typename backend_traits::fragment_program_type; - using binary_to_vertex_program = std::unordered_map, vertex_program_type, program_hash_util::vertex_program_hash, program_hash_util::vertex_program_compare> ; + using binary_to_vertex_program = std::unordered_map ; using binary_to_fragment_program = std::unordered_map; @@ -115,13 +115,13 @@ private: /// bool here to inform that the program was preexisting. std::tuple search_vertex_program(const RSXVertexProgram& rsx_vp) { - const auto& I = m_vertex_shader_cache.find(rsx_vp.data); + const auto& I = m_vertex_shader_cache.find(rsx_vp); if (I != m_vertex_shader_cache.end()) { return std::forward_as_tuple(I->second, true); } LOG_NOTICE(RSX, "VP not found in buffer!"); - vertex_program_type& new_shader = m_vertex_shader_cache[rsx_vp.data]; + vertex_program_type& new_shader = m_vertex_shader_cache[rsx_vp]; backend_traits::recompile_vertex_program(rsx_vp, new_shader, m_next_id++); return std::forward_as_tuple(new_shader, false); @@ -151,7 +151,7 @@ public: const vertex_program_type& get_transform_program(const RSXVertexProgram& rsx_vp) const { - auto I = m_vertex_shader_cache.find(rsx_vp.data); + auto I = m_vertex_shader_cache.find(rsx_vp); if (I != m_vertex_shader_cache.end()) return I->second; throw new EXCEPTION("Trying to get unknow transform program"); diff --git a/rpcs3/Emu/RSX/RSXVertexProgram.h b/rpcs3/Emu/RSX/RSXVertexProgram.h index f16d811011..d90d29fba6 100644 --- a/rpcs3/Emu/RSX/RSXVertexProgram.h +++ b/rpcs3/Emu/RSX/RSXVertexProgram.h @@ -190,7 +190,23 @@ static const std::string rsx_vp_vec_op_names[] = "SEQ", "SFL", "SGT", "SLE", "SNE", "STR", "SSG", "NULL", "NULL", "TXL" }; +struct rsx_vertex_input +{ + u8 location; // between 0 and 15 + u8 size; // between 1 and 4 + u8 frequency; + bool is_modulo; // either modulo frequency or divide frequency + bool is_array; // false if "reg value" + + bool operator==(const rsx_vertex_input other) const + { + return location == other.location && size == other.size && frequency == other.frequency && is_modulo == other.is_modulo && is_array == other.is_array; + } +}; + struct RSXVertexProgram { std::vector data; + std::vector rsx_vertex_inputs; + u32 output_mask; };