rsx: Fix blit surface intersection logic in the surface cache

- Ensure intersection results are committed by pushing a write barrier before the write tag operation
This commit is contained in:
kd-11 2026-07-09 18:44:16 +03:00
parent 5cd5e8435d
commit 10051b7342
6 changed files with 61 additions and 4 deletions

View File

@ -1027,6 +1027,47 @@ namespace rsx
}
}
// Prepare a render target surface for drawing without binding it to the current RTV/DSV set.
// Useful for transfer operations to ensure watertight writes.
template <typename ...Args>
void prepare_transfer_target(
command_list_type command_list,
surface_type surface,
rsx::surface_access access,
Args&&... extra_params)
{
// We need to reintersect the surface against the surface hierarchy tree to avoid data loss
if (!surface->is_depth_surface()) [[ likely ]]
{
bind_address_as_render_targets(
command_list,
surface->base_addr,
surface->format_info.gcm_color_format,
surface->get_aa_mode(),
surface->get_surface_width(),
surface->get_surface_height(),
surface->get_rsx_pitch(),
surface->get_resolution_scaling_config(),
std::forward<Args>(extra_params)...);
}
else
{
bind_address_as_depth_stencil(
command_list,
surface->base_addr,
surface->format_info.gcm_depth_format,
surface->get_aa_mode(),
surface->get_surface_width(),
surface->get_surface_height(),
surface->get_rsx_pitch(),
surface->get_resolution_scaling_config(),
std::forward<Args>(extra_params)...);
}
ensure(access.is_transfer());
surface->memory_barrier(command_list, access);
}
// Create surface on-demand from an RSX image description
template <typename ...Args>
surface_type create_surface_from_rsx_section(
@ -1034,6 +1075,8 @@ namespace rsx
const rsx::image_section_attributes_t& attributes,
Args&&... extra_params)
{
cache_tag = rsx::get_shared_tag();
if (rsx::classify_format(attributes.gcm_format) == RSX_FORMAT_CLASS_COLOR)
{
return bind_address_as_render_targets(

View File

@ -147,6 +147,9 @@ namespace rsx
u8 samples_x = 1;
u8 samples_y = 1;
// AA mode
rsx::surface_antialiasing aa_mode = rsx::surface_antialiasing::center_1_sample;
// Scaling configuration
surface_scaling_config_t resolution_scaling_config;
@ -258,6 +261,8 @@ namespace rsx
void set_aa_mode(rsx::surface_antialiasing aa)
{
aa_mode = aa;
switch (aa)
{
case rsx::surface_antialiasing::center_1_sample:
@ -277,6 +282,11 @@ namespace rsx
}
}
rsx::surface_antialiasing get_aa_mode() const
{
return aa_mode;
}
void set_spp(u8 count)
{
switch (count)

View File

@ -3328,6 +3328,7 @@ namespace rsx
std::forward<Args>(extras)...);
ensure(dst_surface, "Failed to create target surface");
//dst_surface->set_name(fmt::format("Blit target @0x%x", section_attr.address));
if (!dst_area.x1 && !dst_area.y1 && dst_area.x2 == dst_dimensions.width && dst_area.y2 == dst_dimensions.height)
{
@ -3388,7 +3389,9 @@ namespace rsx
}
else
{
// NOTE: This doesn't work very well in case of Cell access
m_rtts.prepare_transfer_target(cmd, dst_subres.surface, rsx::surface_access::transfer_write, std::forward<Args>(extras)...);
// NOTE: This doesn't work very well in case of Cell access (when WCB/WDB is disabled)
// Need to lock the affected memory range and actually attach this subres to a locked_region
dst_subres.surface->on_write_copy(rsx::get_shared_tag(), false, raster_type);

View File

@ -252,7 +252,7 @@ struct gl_render_target_traits
sink->resolution_scaling_config = scaling_config;
sink->set_name(fmt::format("SINK_%u@0x%x", sink->id(), address));
sink->set_spp(ref->get_spp());
sink->set_aa_mode(ref->get_aa_mode());
sink->set_native_pitch(static_cast<u32>(prev.width) * ref->get_bpp() * ref->samples_x);
sink->set_rsx_pitch(ref->get_rsx_pitch());
sink->set_surface_dimensions(prev.width, prev.height, ref->get_rsx_pitch());

View File

@ -941,7 +941,8 @@ namespace vk
}
const bool is_depth = is_depth_surface();
const bool should_read_buffers = is_depth ? !!g_cfg.video.read_depth_buffer : !!g_cfg.video.read_color_buffers;
const bool read_buffers_config = is_depth ? !!g_cfg.video.read_depth_buffer : !!g_cfg.video.read_color_buffers;
const bool should_read_buffers = (state_flags & rsx::surface_state_flags::force_data_load) || read_buffers_config;
if (should_read_buffers)
{

View File

@ -368,7 +368,7 @@ namespace vk
sink->sample_layout = ref->sample_layout;
sink->resolution_scaling_config = scaling_config;
sink->set_spp(ref->get_spp());
sink->set_aa_mode(ref->get_aa_mode());
sink->format_info = ref->format_info;
sink->memory_usage_flags = rsx::surface_usage_flags::storage;
sink->state_flags = rsx::surface_state_flags::erase_bkgnd;