From 47202d5839a6db5abdd471d60176cf7dd5f63d52 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 25 Sep 2017 17:57:24 +0300 Subject: [PATCH] rsx: Set up patch functionality for program coeffecients --- rpcs3/Emu/RSX/Common/ProgramStateCache.h | 97 ++++++++++++++++++++++-- rpcs3/Emu/System.h | 1 + 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index 45eccb38a2..cd28b04dd7 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -151,6 +151,56 @@ protected: return std::forward_as_tuple(new_shader, false); } +public: + + struct program_buffer_patch_entry + { + union + { + u32 hex_key; + f32 fp_key; + }; + + union + { + u32 hex_value; + f32 fp_value; + }; + + program_buffer_patch_entry(f32& key, f32& value) + { + fp_key = key; + fp_value = value; + } + + program_buffer_patch_entry(u32& key, u32& value) + { + hex_key = key; + hex_value = value; + } + }; + + struct + { + std::vector keys; + + void add(program_buffer_patch_entry& e) + { + keys.push_back(e); + } + + void clear() + { + keys.resize(0); + } + + bool is_empty() const + { + return keys.size() == 0; + } + } + patch_table; + public: program_state_cache() = default; ~program_state_cache() @@ -238,13 +288,48 @@ public: verify(HERE), (dst_buffer.size_bytes() >= ::narrow(I->second.FragmentConstantOffsetCache.size()) * 16); size_t offset = 0; - for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache) + if (patch_table.is_empty()) { - void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program; - const __m128i &vector = _mm_loadu_si128((__m128i*)data); - const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask); - _mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector); - offset += sizeof(f32); + for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache) + { + void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program; + const __m128i &vector = _mm_loadu_si128((__m128i*)data); + const __m128i &shuffled_vector = _mm_shuffle_epi8(vector, mask); + _mm_stream_si128((__m128i*)dst_buffer.subspan(offset, 4).data(), shuffled_vector); + offset += 4; + } + } + else + { + for (size_t offset_in_fragment_program : I->second.FragmentConstantOffsetCache) + { + void *data = (char*)fragment_program.addr + (u32)offset_in_fragment_program; + f32* src = (f32*)data; + f32* dst = dst_buffer.subspan(offset, 4).data(); + bool patched; + + for (int i = 0; i < 4; ++i) + { + patched = false; + for (auto& e : patch_table.keys) + { + //TODO: Use fp comparison with fabsf without hurting performance + if (e.hex_key == (u32&)src[i]) + { + dst[i] = e.fp_value; + patched = true; + break; + } + } + + if (!patched) + { + dst[i] = src[i]; + } + } + + offset += 4; + } } } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index b1c86f66d8..c1c8483938 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -331,6 +331,7 @@ struct cfg_root : cfg::node cfg::_bool frame_skip_enabled{this, "Enable Frame Skip"}; cfg::_int<1, 8> consequtive_frames_to_draw{this, "Consecutive Frames To Draw", 1}; cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consecutive Frames To Skip", 1}; + cfg::_int<50, 800> resolution_scale_percent{this, "Resolution Scale", 100}; struct node_d3d12 : cfg::node {