rsx: Implement proper pitch compatibility lookup

- When a single row is required or is all that is available, pitch has
no meaning as the coordinate space changed to 1D
This commit is contained in:
kd-11 2019-03-02 17:40:16 +03:00 committed by kd-11
parent dccb4a4888
commit 7c379432dd
7 changed files with 38 additions and 16 deletions

View File

@ -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();

View File

@ -1040,7 +1040,7 @@ namespace rsx
}
template <bool check_unlocked = false>
std::vector<section_storage_type*> find_texture_from_range(const address_range &test_range, u16 required_pitch = 0, u32 context_mask=0xFF)
std::vector<section_storage_type*> find_texture_from_range(const address_range &test_range, u16 required_pitch = 0, u32 context_mask = 0xFF)
{
std::vector<section_storage_type*> results;
@ -1060,7 +1060,7 @@ namespace rsx
continue;
}
if (required_pitch && tex.get_rsx_pitch() != required_pitch)
if (required_pitch && !rsx::pitch_compatible<false>(&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 &section : 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<true>(tex_range, tex_pitch, lookup_mask);
const auto overlapping_locals = find_texture_from_range<true>(tex_range, tex_height > 1? tex_pitch : 0, lookup_mask);
for (auto& cached_texture : overlapping_locals)
{

View File

@ -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<gl::render_target*>(ds->old_contents)->get_rsx_pitch())
rsx::pitch_compatible(ds, static_cast<gl::render_target*>(ds->old_contents)))
{
gl_state.enable(GL_FALSE, GL_SCISSOR_TEST);

View File

@ -603,7 +603,7 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, bool force_init
}
auto src_texture = static_cast<gl::render_target*>(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;

View File

@ -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<vk::render_target*>(ds->old_contents)->get_rsx_pitch())
rsx::pitch_compatible(ds, static_cast<vk::render_target*>(ds->old_contents)))
{
auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0);
auto render_pass = m_render_passes[rp];

View File

@ -100,7 +100,7 @@ namespace vk
}
auto src_texture = static_cast<vk::render_target*>(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;

View File

@ -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 <typename SurfaceType>
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 <bool __is_surface = true, typename SurfaceType>
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