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 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<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 lines = get_backtrace_symbols(trace);
for (const auto& line : lines)
{
logger.error("%s", line);
logger.print(line);
}
}
}

View file

@ -392,6 +392,9 @@ namespace rsx
ensure(native_pitch);
ensure(rsx_pitch);
// Clear metadata
reset();
base_addr = address;
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
{
return texture_cache_metadata.locked;

View file

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

View file

@ -215,7 +215,7 @@ struct gl_render_target_traits
sink->queue_tag(address);
}
prev.target = sink.get();
sink->on_clone_from(ref);
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->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
@ -294,7 +291,6 @@ struct gl_render_target_traits
}
surface->release();
surface->reset();
}
static

View file

@ -325,7 +325,7 @@ namespace vk
sink->change_layout(cmd, best_layout);
}
prev.target = sink.get();
sink->on_clone_from(ref);
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->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(
@ -416,7 +413,6 @@ namespace vk
}
surface->release();
surface->reset();
}
static void notify_surface_persist(const std::unique_ptr<vk::render_target>& /*surface*/)