rsx: Fix surface metadata life-cycle

- Beware of clone operations. Blindly inheriting the parent's metadata is wrong.
- It is possible, especially when reusing a pre-existing slice, that the parent and child info has diverged
This commit is contained in:
kd-11 2022-12-17 14:19:19 +03:00 committed by kd-11
parent 90cf47cdce
commit 04fb86556a
5 changed files with 49 additions and 14 deletions

View File

@ -4,17 +4,43 @@
namespace utils namespace utils
{ {
namespace stack_trace
{
// Printing utilities
template <typename T>
concept Logger = requires (T& t, const std::string& msg)
{
{ t.print(msg) };
};
struct print_to_log
{
logs::channel& log;
public:
print_to_log(logs::channel& chan)
: log(chan)
{}
void print(const std::string& s)
{
log.error("%s", s);
}
};
}
std::vector<void*> get_backtrace(int max_depth = 255); std::vector<void*> get_backtrace(int max_depth = 255);
std::vector<std::string> get_backtrace_symbols(const std::vector<void*>& stack); std::vector<std::string> get_backtrace_symbols(const std::vector<void*>& stack);
FORCE_INLINE void print_trace(logs::channel& logger, int max_depth = 255) FORCE_INLINE void print_trace(stack_trace::Logger auto& logger, int max_depth = 255)
{ {
const auto trace = get_backtrace(max_depth); const auto trace = get_backtrace(max_depth);
const auto lines = get_backtrace_symbols(trace); const auto lines = get_backtrace_symbols(trace);
for (const auto& line : lines) for (const auto& line : lines)
{ {
logger.error("%s", line); logger.print(line);
} }
} }
} }

View File

@ -392,6 +392,9 @@ namespace rsx
ensure(native_pitch); ensure(native_pitch);
ensure(rsx_pitch); ensure(rsx_pitch);
// Clear metadata
reset();
base_addr = address; base_addr = address;
const u32 size_x = (native_pitch > 8)? (native_pitch - 8) : 0u; const u32 size_x = (native_pitch > 8)? (native_pitch - 8) : 0u;
@ -746,6 +749,19 @@ namespace rsx
} }
} }
void on_clone_from(const render_target_descriptor* ref)
{
if (ref->is_locked() && !is_locked())
{
// Propagate locked state only.
texture_cache_metadata = ref->texture_cache_metadata;
}
rsx_pitch = ref->get_rsx_pitch();
last_use_tag = ref->last_use_tag;
raster_type = ref->raster_type; // Can't actually cut up swizzled data
}
bool is_locked() const bool is_locked() const
{ {
return texture_cache_metadata.locked; return texture_cache_metadata.locked;

View File

@ -583,6 +583,7 @@ namespace rsx
} }
data.flushed = true; data.flushed = true;
update_cache_tag();
} }

View File

@ -215,7 +215,7 @@ struct gl_render_target_traits
sink->queue_tag(address); sink->queue_tag(address);
} }
prev.target = sink.get(); sink->on_clone_from(ref);
if (!sink->old_contents.empty()) if (!sink->old_contents.empty())
{ {
@ -230,11 +230,8 @@ struct gl_render_target_traits
} }
} }
sink->set_rsx_pitch(ref->get_rsx_pitch()); prev.target = sink.get();
sink->set_old_contents_region(prev, false); sink->set_old_contents_region(prev, false);
sink->texture_cache_metadata = ref->texture_cache_metadata;
sink->last_use_tag = ref->last_use_tag;
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
} }
static static
@ -294,7 +291,6 @@ struct gl_render_target_traits
} }
surface->release(); surface->release();
surface->reset();
} }
static static

View File

@ -325,7 +325,7 @@ namespace vk
sink->change_layout(cmd, best_layout); sink->change_layout(cmd, best_layout);
} }
prev.target = sink.get(); sink->on_clone_from(ref);
if (!sink->old_contents.empty()) if (!sink->old_contents.empty())
{ {
@ -340,11 +340,8 @@ namespace vk
} }
} }
sink->rsx_pitch = ref->get_rsx_pitch(); prev.target = sink.get();
sink->set_old_contents_region(prev, false); sink->set_old_contents_region(prev, false);
sink->texture_cache_metadata = ref->texture_cache_metadata;
sink->last_use_tag = ref->last_use_tag;
sink->raster_type = ref->raster_type; // Can't actually cut up swizzled data
} }
static std::unique_ptr<vk::render_target> convert_pitch( static std::unique_ptr<vk::render_target> convert_pitch(
@ -416,7 +413,6 @@ namespace vk
} }
surface->release(); surface->release();
surface->reset();
} }
static void notify_surface_persist(const std::unique_ptr<vk::render_target>& /*surface*/) static void notify_surface_persist(const std::unique_ptr<vk::render_target>& /*surface*/)