mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-16 07:10:40 +00:00
rsx: Fix transfer barriers not triggering resolve target initialization
This commit is contained in:
parent
f7b845d49c
commit
1a73b0a0da
@ -46,14 +46,18 @@ namespace rsx
|
||||
shader_write = 1,
|
||||
transfer_read = 2,
|
||||
transfer_write = 4,
|
||||
|
||||
// Arbitrary r/w flags, use with caution.
|
||||
memory_write = 8,
|
||||
memory_read = 16
|
||||
};
|
||||
|
||||
private:
|
||||
// Meta
|
||||
enum
|
||||
{
|
||||
all_writes = (shader_write | transfer_write),
|
||||
all_reads = (shader_read | transfer_read),
|
||||
all_writes = (shader_write | transfer_write | memory_write),
|
||||
all_reads = (shader_read | transfer_read | memory_read),
|
||||
all_transfer = (transfer_read | transfer_write)
|
||||
};
|
||||
|
||||
@ -80,6 +84,11 @@ namespace rsx
|
||||
return !(value_ & ~all_transfer);
|
||||
}
|
||||
|
||||
inline bool is_transfer_or_read() const // Special; reads and transfers generate MSAA load operations
|
||||
{
|
||||
return !(value_ & ~(all_transfer | all_reads));
|
||||
}
|
||||
|
||||
bool operator == (const surface_access& other) const
|
||||
{
|
||||
return value_ == other.value_;
|
||||
|
@ -438,7 +438,7 @@ void gl::render_target::load_memory(gl::command_context& cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void gl::render_target::initialize_memory(gl::command_context& cmd, bool /*read_access*/)
|
||||
void gl::render_target::initialize_memory(gl::command_context& cmd, rsx::surface_access /*access*/)
|
||||
{
|
||||
const bool memory_load = is_depth_surface() ?
|
||||
!!g_cfg.video.read_depth_buffer :
|
||||
@ -478,7 +478,7 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, rsx::surface_ac
|
||||
if (dirty() && (read_access || state_flags & rsx::surface_state_flags::erase_bkgnd))
|
||||
{
|
||||
// Initialize memory contents if we did not find anything usable
|
||||
initialize_memory(cmd, true);
|
||||
initialize_memory(cmd, access);
|
||||
on_write();
|
||||
}
|
||||
|
||||
@ -523,7 +523,7 @@ void gl::render_target::memory_barrier(gl::command_context& cmd, rsx::surface_ac
|
||||
const auto area = section.dst_rect();
|
||||
if (area.x1 > 0 || area.y1 > 0 || unsigned(area.x2) < width() || unsigned(area.y2) < height())
|
||||
{
|
||||
initialize_memory(cmd, false);
|
||||
initialize_memory(cmd, access);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace gl
|
||||
{
|
||||
void clear_memory(gl::command_context& cmd);
|
||||
void load_memory(gl::command_context& cmd);
|
||||
void initialize_memory(gl::command_context& cmd, bool read_access);
|
||||
void initialize_memory(gl::command_context& cmd, rsx::surface_access access);
|
||||
|
||||
public:
|
||||
render_target(GLuint width, GLuint height, GLenum sized_format, rsx::format_class format_class)
|
||||
|
@ -279,7 +279,7 @@ namespace vk
|
||||
state_flags &= ~rsx::surface_state_flags::erase_bkgnd;
|
||||
}
|
||||
|
||||
void render_target::initialize_memory(vk::command_buffer& cmd, bool read_access)
|
||||
void render_target::initialize_memory(vk::command_buffer& cmd, rsx::surface_access access)
|
||||
{
|
||||
const bool is_depth = is_depth_surface();
|
||||
const bool should_read_buffers = is_depth ? !!g_cfg.video.read_depth_buffer : !!g_cfg.video.read_color_buffers;
|
||||
@ -288,7 +288,7 @@ namespace vk
|
||||
{
|
||||
clear_memory(cmd, this);
|
||||
|
||||
if (read_access && samples() > 1)
|
||||
if (samples() > 1 && access.is_transfer_or_read())
|
||||
{
|
||||
// Only clear the resolve surface if reading from it, otherwise it's a waste
|
||||
clear_memory(cmd, get_resolve_target_safe(cmd));
|
||||
@ -369,7 +369,6 @@ namespace vk
|
||||
|
||||
void render_target::memory_barrier(vk::command_buffer& cmd, rsx::surface_access access)
|
||||
{
|
||||
const bool read_access = access.is_read();
|
||||
const bool is_depth = is_depth_surface();
|
||||
const bool should_read_buffers = is_depth ? !!g_cfg.video.read_depth_buffer : !!g_cfg.video.read_color_buffers;
|
||||
|
||||
@ -385,7 +384,7 @@ namespace vk
|
||||
}
|
||||
}
|
||||
|
||||
if (!read_access && write_barrier_sync_tag != 0)
|
||||
if (access == rsx::surface_access::shader_write && write_barrier_sync_tag != 0)
|
||||
{
|
||||
if (current_layout == VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
@ -433,7 +432,7 @@ namespace vk
|
||||
if (state_flags & rsx::surface_state_flags::erase_bkgnd)
|
||||
{
|
||||
// NOTE: This step CAN introduce MSAA flags!
|
||||
initialize_memory(cmd, read_access);
|
||||
initialize_memory(cmd, access);
|
||||
|
||||
ensure(state_flags == rsx::surface_state_flags::ready);
|
||||
on_write(rsx::get_shared_tag(), static_cast<rsx::surface_state_flags>(msaa_flags));
|
||||
@ -441,7 +440,7 @@ namespace vk
|
||||
|
||||
if (msaa_flags & rsx::surface_state_flags::require_resolve)
|
||||
{
|
||||
if (read_access)
|
||||
if (access.is_transfer_or_read())
|
||||
{
|
||||
// Only do this step when read access is required
|
||||
get_resolve_target_safe(cmd);
|
||||
@ -450,7 +449,7 @@ namespace vk
|
||||
}
|
||||
else if (msaa_flags & rsx::surface_state_flags::require_unresolve)
|
||||
{
|
||||
if (!read_access)
|
||||
if (access == rsx::surface_access::shader_write)
|
||||
{
|
||||
// Only do this step when it is needed to start rendering
|
||||
ensure(resolve_surface);
|
||||
@ -521,7 +520,7 @@ namespace vk
|
||||
else if (state_flags & rsx::surface_state_flags::erase_bkgnd)
|
||||
{
|
||||
// Might introduce MSAA flags
|
||||
initialize_memory(cmd, false);
|
||||
initialize_memory(cmd, rsx::surface_access::memory_write);
|
||||
ensure(state_flags == rsx::surface_state_flags::ready);
|
||||
}
|
||||
|
||||
@ -549,14 +548,14 @@ namespace vk
|
||||
clear_rw_barrier();
|
||||
|
||||
state_flags |= rsx::surface_state_flags::erase_bkgnd;
|
||||
initialize_memory(cmd, read_access);
|
||||
initialize_memory(cmd, access);
|
||||
ensure(state_flags == rsx::surface_state_flags::ready);
|
||||
}
|
||||
|
||||
// NOTE: Optimize flag relates to stencil resolve/unresolve for NVIDIA.
|
||||
on_write_copy(newest_tag, optimize_copy);
|
||||
|
||||
if (!read_access && samples() > 1)
|
||||
if (access == rsx::surface_access::shader_write && samples() > 1)
|
||||
{
|
||||
// Write barrier, must initialize
|
||||
unresolve(cmd);
|
||||
|
@ -34,8 +34,8 @@ namespace vk
|
||||
void clear_memory(vk::command_buffer& cmd, vk::image* surface);
|
||||
// Load memory from cell and use to initialize the surface
|
||||
void load_memory(vk::command_buffer& cmd);
|
||||
// Generic - chooses whether to clear or load
|
||||
void initialize_memory(vk::command_buffer& cmd, bool read_access);
|
||||
// Generic - chooses whether to clear or load.
|
||||
void initialize_memory(vk::command_buffer& cmd, rsx::surface_access access);
|
||||
|
||||
public:
|
||||
u64 frame_tag = 0; // frame id when invalidated, 0 if not invalid
|
||||
|
Loading…
Reference in New Issue
Block a user