diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 62309a0ce7..cf46d54fea 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -50,11 +50,22 @@ namespace rsx GcmTileInfo *tile = nullptr; rsx::surface_antialiasing aa_mode = rsx::surface_antialiasing::center_1_sample; + u16 raster_offset_x = 0; + u16 raster_offset_y = 0; + u32 raster_address_offset = 0; + virtual image_storage_type get_surface() const = 0; virtual u16 get_surface_width() const = 0; virtual u16 get_surface_height() const = 0; virtual u16 get_rsx_pitch() const = 0; virtual u16 get_native_pitch() const = 0; + + void set_raster_offset(u16 x, u16 y, u8 bpp) + { + raster_offset_x = x; + raster_offset_y = y; + raster_address_offset = (y * get_rsx_pitch()) + (x * bpp); + } }; /** diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 803c7f6113..c23a58c285 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1233,7 +1233,7 @@ namespace rsx //TODO: When framebuffer Y compression is properly handled, this section can be removed. A more accurate framebuffer storage check exists below this block if (auto texptr = m_rtts.get_texture_from_render_target_if_applicable(texaddr)) { - if (test_framebuffer(texaddr)) + if (test_framebuffer(texaddr + texptr->raster_address_offset)) { return process_framebuffer_resource(texptr, texaddr, tex.format(), m_rtts, tex_width, tex_height, extended_dimension, false); } @@ -1246,7 +1246,7 @@ namespace rsx if (auto texptr = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr)) { - if (test_framebuffer(texaddr)) + if (test_framebuffer(texaddr + texptr->raster_address_offset)) { return process_framebuffer_resource(texptr, texaddr, tex.format(), m_rtts, tex_width, tex_height, extended_dimension, true); } @@ -1282,7 +1282,7 @@ namespace rsx if (rsc.surface) { //TODO: Check that this region is not cpu-dirty before doing a copy - if (!test_framebuffer(rsc.base_address)) + if (!test_framebuffer(rsc.base_address + rsc.surface->raster_address_offset)) { m_rtts.invalidate_surface_address(rsc.base_address, rsc.is_depth_surface); invalidate_address(rsc.base_address, false, true, std::forward(extras)...); @@ -1464,14 +1464,14 @@ namespace rsx src_is_render_target = false; } - if (src_is_render_target && !test_framebuffer(src_subres.base_address)) + if (src_is_render_target && !test_framebuffer(src_subres.base_address + src_subres.surface->raster_address_offset)) { m_rtts.invalidate_surface_address(src_subres.base_address, src_subres.is_depth_surface); invalidate_address(src_subres.base_address, false, true, std::forward(extras)...); src_is_render_target = false; } - if (dst_is_render_target && !test_framebuffer(dst_subres.base_address)) + if (dst_is_render_target && !test_framebuffer(dst_subres.base_address + dst_subres.surface->raster_address_offset)) { m_rtts.invalidate_surface_address(dst_subres.base_address, dst_subres.is_depth_surface); invalidate_address(dst_subres.base_address, false, true, std::forward(extras)...); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 1ea5477518..31e2f937e5 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -165,6 +165,8 @@ void GLGSRender::init_buffers(bool skip_reading) const u16 clip_horizontal = rsx::method_registers.surface_clip_width(); const u16 clip_vertical = rsx::method_registers.surface_clip_height(); + const u16 clip_x = rsx::method_registers.surface_clip_origin_x(); + const u16 clip_y = rsx::method_registers.surface_clip_origin_y(); framebuffer_status_valid = false; @@ -205,6 +207,7 @@ void GLGSRender::init_buffers(bool skip_reading) const auto color_offsets = get_offsets(); const auto color_locations = get_locations(); const auto aa_mode = rsx::method_registers.surface_antialias(); + const auto bpp = get_format_block_size_in_bytes(surface_format); for (int i = 0; i < rsx::limits::color_buffers_count; ++i) { @@ -244,7 +247,11 @@ void GLGSRender::init_buffers(bool skip_reading) rtt->tile = find_tile(color_offsets[i], color_locations[i]); rtt->aa_mode = aa_mode; - m_gl_texture_cache.tag_framebuffer(surface_addresses[i]); + rtt->set_raster_offset(clip_x, clip_y, bpp); + m_gl_texture_cache.notify_surface_changed(surface_addresses[i]); + + if (surface_info[i].pitch) + m_gl_texture_cache.tag_framebuffer(surface_addresses[i] + rtt->raster_address_offset); } else surface_info[i] = {}; @@ -253,8 +260,13 @@ void GLGSRender::init_buffers(bool skip_reading) if (std::get<0>(m_rtts.m_bound_depth_stencil)) { auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); + u8 texel_size = 2; + if (depth_format == rsx::surface_depth_format::z24s8) + { draw_fbo.depth_stencil = *ds; + texel_size = 4; + } else draw_fbo.depth = *ds; @@ -278,7 +290,11 @@ void GLGSRender::init_buffers(bool skip_reading) } ds->aa_mode = aa_mode; - m_gl_texture_cache.tag_framebuffer(depth_address); + ds->set_raster_offset(clip_x, clip_y, texel_size); + m_gl_texture_cache.notify_surface_changed(depth_address); + + if (depth_surface_info.pitch) + m_gl_texture_cache.tag_framebuffer(depth_address + ds->raster_address_offset); } else depth_surface_info = {}; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 6d55de692e..299f457342 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2406,6 +2406,8 @@ void VKGSRender::prepare_rtts() std::vector bound_images; bound_images.reserve(5); + const auto bpp = get_format_block_size_in_bytes(rsx::method_registers.surface_color()); + for (u8 index : draw_buffers) { auto surface = std::get<1>(m_rtts.m_bound_render_targets[index]); @@ -2423,8 +2425,11 @@ void VKGSRender::prepare_rtts() } surface->aa_mode = aa_mode; - m_texture_cache.tag_framebuffer(surface_addresses[index]); + surface->set_raster_offset(clip_x, clip_y, bpp); m_texture_cache.notify_surface_changed(surface_addresses[index]); + + if (m_surface_info[index].pitch) + m_texture_cache.tag_framebuffer(surface_addresses[index] + surface->raster_address_offset); } if (std::get<0>(m_rtts.m_bound_depth_stencil) != 0) @@ -2440,8 +2445,11 @@ void VKGSRender::prepare_rtts() m_depth_surface_info.pitch = 0; ds->aa_mode = aa_mode; - m_texture_cache.tag_framebuffer(zeta_address); + ds->set_raster_offset(clip_x, clip_y, get_pixel_size(rsx::method_registers.surface_depth_fmt())); m_texture_cache.notify_surface_changed(zeta_address); + + if (m_depth_surface_info.pitch) + m_texture_cache.tag_framebuffer(zeta_address + ds->raster_address_offset); } m_draw_buffers_count = static_cast(draw_buffers.size()); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 41bc2284cb..b64903c348 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -1171,6 +1171,26 @@ namespace rsx { return registers[NV4097_SET_TRANSFORM_BRANCH_BITS]; } + + u16 msaa_sample_mask() + { + return decode().msaa_sample_mask(); + } + + bool msaa_enabled() + { + return decode().msaa_enabled(); + } + + bool msaa_alpha_to_coverage_enabled() + { + return decode().msaa_alpha_to_coverage(); + } + + bool msaa_alpha_to_one_enabled() + { + return decode().msaa_alpha_to_one(); + } }; extern rsx_state method_registers;