diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 2c17febc52..3de6b35e42 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -997,7 +997,7 @@ namespace rsx continue; surface = std::get<1>(tex_info).get(); - if (surface->get_rsx_pitch() != requested_pitch) + if (!rsx::pitch_compatible(surface, requested_pitch, requested_height)) continue; if (requested_width == 0 || requested_height == 0) @@ -1023,7 +1023,7 @@ namespace rsx continue; surface = std::get<1>(tex_info).get(); - if (surface->get_rsx_pitch() != requested_pitch) + if (!rsx::pitch_compatible(surface, requested_pitch, requested_height)) continue; if (requested_width == 0 || requested_height == 0) @@ -1059,7 +1059,7 @@ namespace rsx auto surface = std::get<1>(tex_info).get(); const auto pitch = surface->get_rsx_pitch(); - if (pitch != required_pitch) + if (!rsx::pitch_compatible(surface, required_pitch, required_height)) continue; const auto texture_size = pitch * surface->get_surface_height(); diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 64a05837ac..42e87c4d27 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1040,7 +1040,7 @@ namespace rsx } template - std::vector find_texture_from_range(const address_range &test_range, u16 required_pitch = 0, u32 context_mask=0xFF) + std::vector find_texture_from_range(const address_range &test_range, u16 required_pitch = 0, u32 context_mask = 0xFF) { std::vector results; @@ -1060,7 +1060,7 @@ namespace rsx continue; } - if (required_pitch && tex.get_rsx_pitch() != required_pitch) + if (required_pitch && !rsx::pitch_compatible(&tex, required_pitch, UINT16_MAX)) { continue; } @@ -1575,8 +1575,7 @@ namespace rsx for (u32 index = 0; index < local.size(); ++index) { - if (local[index]->get_rsx_pitch() != pitch || - local[index]->get_context() != rsx::texture_upload_context::blit_engine_dst) + if (local[index]->get_context() != rsx::texture_upload_context::blit_engine_dst) continue; sort_list.push_back({ local[index]->last_write_tag, 1, index }); @@ -1742,9 +1741,6 @@ namespace rsx { for (auto §ion : local) { - if (section->get_rsx_pitch() != pitch) - continue; - add_local_resource(section, current_address, slice, false); } } @@ -1791,7 +1787,7 @@ namespace rsx u16 tex_width, u16 tex_height, u16 tex_depth, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension) { - if (texptr->get_rsx_pitch() != tex_pitch) + if (!rsx::pitch_compatible(texptr, tex_pitch, tex_height)) { return false; } @@ -2008,7 +2004,7 @@ namespace rsx // Check shader_read storage. In a given scene, reads from local memory far outnumber reads from the surface cache const u32 lookup_mask = (is_compressed_format)? rsx::texture_upload_context::shader_read : rsx::texture_upload_context::shader_read | rsx::texture_upload_context::blit_engine_dst | rsx::texture_upload_context::blit_engine_src; - const auto overlapping_locals = find_texture_from_range(tex_range, tex_pitch, lookup_mask); + const auto overlapping_locals = find_texture_from_range(tex_range, tex_height > 1? tex_pitch : 0, lookup_mask); for (auto& cached_texture : overlapping_locals) { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 4d660add5b..d18a2d148a 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -216,7 +216,7 @@ void GLGSRender::end() // Handle special memory barrier for ARGB8->D24S8 in an active DSV if (ds && ds->old_contents != nullptr && ds->old_contents->get_internal_format() == gl::texture::internal_format::rgba8 && - ds->get_rsx_pitch() == static_cast(ds->old_contents)->get_rsx_pitch()) + rsx::pitch_compatible(ds, static_cast(ds->old_contents))) { gl_state.enable(GL_FALSE, GL_SCISSOR_TEST); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 40ecdad460..23b371bd40 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -603,7 +603,7 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, bool force_init } auto src_texture = static_cast(old_contents); - if (src_texture->get_rsx_pitch() != get_rsx_pitch()) + if (!rsx::pitch_compatible(this, src_texture)) { LOG_TRACE(RSX, "Pitch mismatch, could not transfer inherited memory"); return; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 16ea6240c1..50019c77da 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1436,7 +1436,7 @@ void VKGSRender::end() auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); if (ds && ds->old_contents && ds->old_contents->info.format == VK_FORMAT_B8G8R8A8_UNORM && - ds->get_rsx_pitch() == static_cast(ds->old_contents)->get_rsx_pitch()) + rsx::pitch_compatible(ds, static_cast(ds->old_contents))) { auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0); auto render_pass = m_render_passes[rp]; diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index e7c3837d18..c85cc94bde 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -100,7 +100,7 @@ namespace vk } auto src_texture = static_cast(old_contents); - if (src_texture->get_rsx_pitch() != get_rsx_pitch()) + if (!rsx::pitch_compatible(this, src_texture)) { LOG_TRACE(RSX, "Pitch mismatch, could not transfer inherited memory"); return; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 6b42e8fa78..d1acbd85b2 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -544,6 +544,32 @@ namespace rsx return std::make_tuple(u16(dst_w / scale_x), u16(dst_h / scale_y), dst_w, dst_h); } + template + inline bool pitch_compatible(SurfaceType* a, SurfaceType* b) + { + if (a->get_surface_height() == 1 || b->get_surface_height() == 1) + return true; + + return (a->get_rsx_pitch() == b->get_rsx_pitch()); + } + + template + inline bool pitch_compatible(SurfaceType* surface, u16 pitch_required, u16 height_required) + { + if constexpr (__is_surface) + { + if (height_required == 1 || surface->get_surface_height() == 1) + return true; + } + else + { + if (height_required == 1 || surface->get_height() == 1) + return true; + } + + return (surface->get_rsx_pitch() == pitch_required); + } + /** * Remove restart index and emulate using degenerate triangles * Can be used as a workaround when restart_index doesnt work too well