mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
rsx: Invalidate surface cache slots that are trampled by buffer writes.
This commit is contained in:
parent
0403231a0d
commit
dba48d6387
27
Utilities/deferred_op.hpp
Normal file
27
Utilities/deferred_op.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
// Generic deferred routine wrapper
|
||||
// Use-case is similar to "defer" statement in other languages, just invokes a callback when the object goes out of scope
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
template <typename F>
|
||||
requires std::is_invocable_v<F>
|
||||
class deferred_op
|
||||
{
|
||||
public:
|
||||
deferred_op(F&& callback)
|
||||
: m_callback(callback)
|
||||
{}
|
||||
|
||||
~deferred_op()
|
||||
{
|
||||
m_callback();
|
||||
}
|
||||
|
||||
private:
|
||||
F m_callback;
|
||||
};
|
||||
}
|
||||
|
|
@ -1411,6 +1411,12 @@ void GLGSRender::on_guest_texture_read()
|
|||
enqueue_host_context_write(::offset32(&rsx::host_gpu_context_t::texture_load_complete_event), 8, &event_id);
|
||||
}
|
||||
|
||||
void GLGSRender::write_barrier(u32 address, u32 range)
|
||||
{
|
||||
ensure(is_current_thread());
|
||||
m_rtts.invalidate_range(utils::address_range32::start_length(address, range));
|
||||
}
|
||||
|
||||
void GLGSRender::begin_occlusion_query(rsx::reports::occlusion_query_info* query)
|
||||
{
|
||||
query->result = 0;
|
||||
|
|
|
|||
|
|
@ -192,8 +192,12 @@ public:
|
|||
|
||||
gl::work_item& post_flush_request(u32 address, gl::texture_cache::thrashed_set& flush_data);
|
||||
|
||||
// NV3089
|
||||
bool scaled_image_from_memory(const rsx::blit_src_info& src_info, const rsx::blit_dst_info& dst_info, bool interpolate) override;
|
||||
|
||||
// Sync
|
||||
void write_barrier(u32 address, u32 range) override;
|
||||
|
||||
// ZCULL
|
||||
void begin_occlusion_query(rsx::reports::occlusion_query_info* query) override;
|
||||
void end_occlusion_query(rsx::reports::occlusion_query_info* query) override;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,44 @@
|
|||
#include "Emu/RSX/Core/RSXReservationLock.hpp"
|
||||
#include "Emu/RSX/Host/MM.h"
|
||||
|
||||
#include "Utilities/deferred_op.hpp"
|
||||
|
||||
#include "context_accessors.define.h"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
namespace nv0039
|
||||
{
|
||||
// Transfer with stride
|
||||
inline void block2d_copy_with_stride(u8* dst, const u8* src, u32 width, u32 height, u32 src_pitch, u32 dst_pitch, u8 src_stride, u8 dst_stride)
|
||||
{
|
||||
for (u32 row = 0; row < height; ++row)
|
||||
{
|
||||
auto dst_ptr = dst;
|
||||
auto src_ptr = src;
|
||||
while (src_ptr < src + width)
|
||||
{
|
||||
*dst_ptr = *src_ptr;
|
||||
|
||||
src_ptr += src_stride;
|
||||
dst_ptr += dst_stride;
|
||||
}
|
||||
|
||||
dst += dst_pitch;
|
||||
src += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
inline void block2d_copy(u8* dst, const u8* src, u32 width, u32 height, u32 src_pitch, u32 dst_pitch)
|
||||
{
|
||||
for (u32 i = 0; i < height; ++i)
|
||||
{
|
||||
std::memcpy(dst, src, width);
|
||||
dst += dst_pitch;
|
||||
src += src_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void buffer_notify(context* ctx, u32, u32 arg)
|
||||
{
|
||||
s32 in_pitch = REGS(ctx)->nv0039_input_pitch();
|
||||
|
|
@ -56,6 +88,13 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
// Deferred write_barrier on RSX side
|
||||
utils::deferred_op deferred([&]()
|
||||
{
|
||||
RSX(ctx)->write_barrier(write_address, write_length);
|
||||
// res->release(0);
|
||||
});
|
||||
|
||||
auto res = ::rsx::reservation_lock<true>(write_address, write_length, read_address, read_length);
|
||||
|
||||
u8* dst = vm::_ptr<u8>(write_address);
|
||||
|
|
@ -81,68 +120,34 @@ namespace rsx
|
|||
// The formats are just input channel strides. You can use this to do cool tricks like gathering channels
|
||||
// Very rare, only seen in use by Destiny
|
||||
// TODO: Hw accel
|
||||
for (u32 row = 0; row < line_count; ++row)
|
||||
{
|
||||
auto dst_ptr = dst;
|
||||
auto src_ptr = src;
|
||||
while (src_ptr < src + line_length)
|
||||
{
|
||||
*dst_ptr = *src_ptr;
|
||||
|
||||
src_ptr += in_format;
|
||||
dst_ptr += out_format;
|
||||
}
|
||||
|
||||
dst += out_pitch;
|
||||
src += in_pitch;
|
||||
}
|
||||
block2d_copy_with_stride(dst, src, line_length, line_count, in_pitch, out_pitch, in_format, out_format);
|
||||
return;
|
||||
}
|
||||
else if (is_overlapping) [[ unlikely ]]
|
||||
{
|
||||
if (is_block_transfer)
|
||||
{
|
||||
std::memmove(dst, src, read_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<u8> temp(line_length * line_count);
|
||||
u8* buf = temp.data();
|
||||
|
||||
for (u32 y = 0; y < line_count; ++y)
|
||||
{
|
||||
std::memcpy(buf, src, line_length);
|
||||
buf += line_length;
|
||||
src += in_pitch;
|
||||
}
|
||||
|
||||
buf = temp.data();
|
||||
|
||||
for (u32 y = 0; y < line_count; ++y)
|
||||
{
|
||||
std::memcpy(dst, buf, line_length);
|
||||
buf += line_length;
|
||||
dst += out_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!is_overlapping)
|
||||
{
|
||||
if (is_block_transfer)
|
||||
{
|
||||
std::memcpy(dst, src, read_length);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = 0; i < line_count; ++i)
|
||||
{
|
||||
std::memcpy(dst, src, line_length);
|
||||
dst += out_pitch;
|
||||
src += in_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
block2d_copy(dst, src, line_length, line_count, in_pitch, out_pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
//res->release(0);
|
||||
if (is_block_transfer)
|
||||
{
|
||||
std::memmove(dst, src, read_length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle overlapping 2D range using double-copy to temp.
|
||||
std::vector<u8> temp(line_length * line_count);
|
||||
u8* buf = temp.data();
|
||||
|
||||
block2d_copy(buf, src, line_length, line_count, in_pitch, line_length);
|
||||
block2d_copy(dst, buf, line_length, line_count, line_length, out_pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,6 +374,7 @@ namespace rsx
|
|||
// sync
|
||||
void sync();
|
||||
flags32_t read_barrier(u32 memory_address, u32 memory_range, bool unconditional);
|
||||
virtual void write_barrier(u32 memory_address, u32 memory_range) {}
|
||||
virtual void sync_hint(FIFO::interrupt_hint hint, reports::sync_hint_payload_t payload);
|
||||
virtual bool release_GCM_label(u32 /*address*/, u32 /*value*/) { return false; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1613,6 +1613,12 @@ void VKGSRender::on_guest_texture_read(const vk::command_buffer& cmd)
|
|||
vkCmdUpdateBuffer(cmd, m_host_object_data->value, ::offset32(&vk::host_data_t::texture_load_complete_event), sizeof(u64), &event_id);
|
||||
}
|
||||
|
||||
void VKGSRender::write_barrier(u32 address, u32 range)
|
||||
{
|
||||
ensure(is_current_thread());
|
||||
m_rtts.invalidate_range(utils::address_range32::start_length(address, range));
|
||||
}
|
||||
|
||||
void VKGSRender::sync_hint(rsx::FIFO::interrupt_hint hint, rsx::reports::sync_hint_payload_t payload)
|
||||
{
|
||||
rsx::thread::sync_hint(hint, payload);
|
||||
|
|
|
|||
|
|
@ -249,6 +249,8 @@ public:
|
|||
void set_scissor(bool clip_viewport);
|
||||
void bind_viewport();
|
||||
|
||||
// Sync
|
||||
void write_barrier(u32 address, u32 range) override;
|
||||
void sync_hint(rsx::FIFO::interrupt_hint hint, rsx::reports::sync_hint_payload_t payload) override;
|
||||
bool release_GCM_label(u32 address, u32 data) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -546,6 +546,7 @@
|
|||
<ClInclude Include="..\3rdparty\stblib\stb\stb_image.h" />
|
||||
<ClInclude Include="..\Utilities\address_range.h" />
|
||||
<ClInclude Include="..\Utilities\cheat_info.h" />
|
||||
<ClInclude Include="..\Utilities\deferred_op.hpp" />
|
||||
<ClInclude Include="..\Utilities\simple_ringbuf.h" />
|
||||
<ClInclude Include="..\Utilities\stack_trace.h" />
|
||||
<ClInclude Include="..\Utilities\transactional_storage.h" />
|
||||
|
|
|
|||
|
|
@ -2755,6 +2755,9 @@
|
|||
<ClInclude Include="Emu\RSX\Common\reverse_ptr.hpp">
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Utilities\deferred_op.hpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||
|
|
|
|||
Loading…
Reference in a new issue