diff --git a/rpcs3/Emu/RSX/NV47/HW/nv406e.cpp b/rpcs3/Emu/RSX/NV47/HW/nv406e.cpp index ced6c3f386..242b1bdb73 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv406e.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv406e.cpp @@ -25,6 +25,9 @@ namespace rsx RSX(ctx)->sync_point_request.release(true); const u32 addr = get_address(REGS(ctx)->semaphore_offset_406e(), REGS(ctx)->semaphore_context_dma_406e()); + // Syncronization point, may be associated with memory changes without actually changing addresses + RSX(ctx)->m_graphics_state |= rsx::pipeline_state::fragment_program_ucode_dirty; + const auto& sema = vm::_ref(addr).val; if (sema == arg) diff --git a/rpcs3/Emu/RSX/NV47/HW/nv47_sync.hpp b/rpcs3/Emu/RSX/NV47/HW/nv47_sync.hpp index 9c153b2056..77a1a10b11 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv47_sync.hpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv47_sync.hpp @@ -44,6 +44,9 @@ namespace rsx // Manually flush the pipeline. // It is possible to stream report writes using the host GPU, but that generates too much submit traffic. RSX(ctx)->sync(); + + // Syncronization point, may be associated with memory changes without actually changing addresses + RSX(ctx)->m_graphics_state |= rsx::pipeline_state::fragment_program_ucode_dirty; } } diff --git a/rpcs3/Emu/RSX/Program/ProgramStateCache.h b/rpcs3/Emu/RSX/Program/ProgramStateCache.h index ae0e8f6258..21f33ed6a6 100644 --- a/rpcs3/Emu/RSX/Program/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Program/ProgramStateCache.h @@ -213,6 +213,7 @@ protected: recompile = inserted; prev_map_count = umax; prev_rsx_count = umax; + prev_vp = nullptr; map_invl_count++; } @@ -225,7 +226,7 @@ protected: } /// bool here to inform that the program was preexisting. - std::tuple search_fragment_program(const RSXFragmentProgram& rsx_fp, usz /*rsx_fp_invalidation_count*/) + std::tuple search_fragment_program(const RSXFragmentProgram& rsx_fp, usz rsx_fp_invalidation_count) { bool recompile = false; typename binary_to_fragment_program::iterator it; @@ -242,13 +243,14 @@ protected: // prev_vp must be non-null here if (prev_fp->first.ucode_length == rsx_fp.ucode_length && prev_fp->first.texcoord_control_mask == rsx_fp.texcoord_control_mask) { - // if (rsx_fp_invalidation_count != umax && prev_rsx_count == rsx_fp_invalidation_count) - // { - // return std::forward_as_tuple(prev_fp->second, true); - // } + if (rsx_fp_invalidation_count != umax && prev_rsx_count == rsx_fp_invalidation_count) + { + return std::forward_as_tuple(prev_fp->second, true); + } if (program_hash_util::fragment_program_compare()(prev_fp->first, rsx_fp)) { + prev_rsx_count = rsx_fp_invalidation_count; return std::forward_as_tuple(prev_fp->second, true); } } @@ -258,7 +260,7 @@ protected: if (I != m_fragment_shader_cache.end()) { prev_fp = &*I; - //prev_rsx_count = rsx_fp_invalidation_count; + prev_rsx_count = rsx_fp_invalidation_count; prev_map_count = map_invl_count; return std::forward_as_tuple(I->second, true); } @@ -270,6 +272,7 @@ protected: new_shader = &(it->second); prev_map_count = umax; prev_rsx_count = umax; + prev_fp = nullptr; map_invl_count++; } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 91efee217b..3ea42c60df 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1904,6 +1904,7 @@ namespace rsx } m_graphics_state.clear(rsx::pipeline_state::fragment_program_ucode_dirty); + fragment_program_invalidation_count++; // Request for update of fragment constants if the program block is invalidated m_graphics_state |= rsx::pipeline_state::fragment_constants_dirty; @@ -2046,6 +2047,7 @@ namespace rsx ensure(!m_graphics_state.test(rsx::pipeline_state::fragment_program_ucode_dirty)); m_graphics_state.clear(rsx::pipeline_state::fragment_program_dirty); + fragment_program_invalidation_count++; current_fragment_program.ctrl = m_ctx->register_state->shader_control() & (CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS | CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT); current_fragment_program.texcoord_control_mask = m_ctx->register_state->texcoord_control_mask();