mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 19:22:48 +01:00
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:
parent
90cf47cdce
commit
04fb86556a
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -583,6 +583,7 @@ namespace rsx
|
||||
}
|
||||
|
||||
data.flushed = true;
|
||||
update_cache_tag();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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*/)
|
||||
|
Loading…
Reference in New Issue
Block a user