mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-11 02:24:44 -06:00
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:
parent
5cd5e8435d
commit
10051b7342
@ -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(
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user