From 07f61db24a26f719dd91d22cfc473ef905bd90ef Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 15 Nov 2017 18:50:41 +0300 Subject: [PATCH] rsx: Try to take the context for the surface creation into account --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 8 +++++-- rpcs3/Emu/RSX/GL/GLGSRender.h | 2 +- rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 10 +++++---- rpcs3/Emu/RSX/RSXThread.h | 8 +++++++ rpcs3/Emu/RSX/VK/VKGSRender.cpp | 31 +++++++++++++++------------- rpcs3/Emu/RSX/VK/VKGSRender.h | 4 ++-- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 45183984d1..78da6ae348 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -174,7 +174,7 @@ void GLGSRender::begin() if (conditional_render_enabled && conditional_render_test_failed) return; - init_buffers(); + init_buffers(rsx::framebuffer_creation_context::context_draw); } namespace @@ -927,7 +927,11 @@ bool GLGSRender::do_method(u32 cmd, u32 arg) if (arg & 0xF3) { //Only do all this if we have actual work to do - init_buffers(true); + u8 ctx = rsx::framebuffer_creation_context::context_draw; + if (arg & 0xF0) ctx |= rsx::framebuffer_creation_context::context_clear_color; + if (arg & 0x3) ctx |= rsx::framebuffer_creation_context::context_clear_depth; + + init_buffers((rsx::framebuffer_creation_context)ctx, true); synchronize_buffers(); clear_surface(arg); } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 9851a9c245..e2e561d15f 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -398,7 +398,7 @@ private: rsx::vertex_input_layout m_vertex_layout = {}; void clear_surface(u32 arg); - void init_buffers(bool skip_reading = false); + void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false); bool check_program_state(); void load_program(u32 vertex_base, u32 vertex_count); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index a47781eace..7a75b8739e 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -149,7 +149,7 @@ namespace } } -void GLGSRender::init_buffers(bool skip_reading) +void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool skip_reading) { if (draw_fbo && !m_rtts_dirty) { @@ -209,9 +209,10 @@ void GLGSRender::init_buffers(bool skip_reading) zeta_pitch >= required_z_pitch) { LOG_TRACE(RSX, "Framebuffer at 0x%X has aliasing color/depth targets, zeta_pitch = %d, color_pitch=%d", depth_address, zeta_pitch, pitchs[index]); - m_framebuffer_state_contested = true; - - if (rsx::method_registers.depth_test_enabled() || + //TODO: Research clearing both depth AND color + //TODO: If context is creation_draw, deal with possibility of a lost buffer clear + if (context == rsx::framebuffer_creation_context::context_clear_depth || + rsx::method_registers.depth_test_enabled() || (!rsx::method_registers.color_write_enabled() && rsx::method_registers.depth_write_enabled()) || !!(rsx::method_registers.shader_control() & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)) { @@ -222,6 +223,7 @@ void GLGSRender::init_buffers(bool skip_reading) { // Use address for color data depth_address = 0; + m_framebuffer_state_contested = true; break; } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 263fb4e0a7..a4916b0d7e 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -44,6 +44,14 @@ namespace rsx }; } + enum framebuffer_creation_context : u8 + { + context_draw = 0, + context_clear_color = 1, + context_clear_depth = 2, + context_clear_all = context_clear_color | context_clear_depth + }; + u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size); u32 get_address(u32 offset, u32 location); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index fbff89b6e1..e6b23f5db0 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -912,7 +912,7 @@ void VKGSRender::begin() if (skip_frame || renderer_unavailable) return; - init_buffers(); + init_buffers(rsx::framebuffer_creation_context::context_draw); if (!framebuffer_status_valid) return; @@ -1549,7 +1549,10 @@ void VKGSRender::clear_surface(u32 mask) // Ignore invalid clear flags if (!(mask & 0xF3)) return; - init_buffers(); + u8 ctx = rsx::framebuffer_creation_context::context_draw; + if (mask & 0xF0) ctx |= rsx::framebuffer_creation_context::context_clear_color; + if (mask & 0x3) ctx |= rsx::framebuffer_creation_context::context_clear_depth; + init_buffers((rsx::framebuffer_creation_context)ctx); if (!framebuffer_status_valid) return; @@ -2242,7 +2245,7 @@ static const u32 mr_color_pitch[rsx::limits::color_buffers_count] = NV4097_SET_SURFACE_PITCH_D }; -void VKGSRender::init_buffers(bool skip_reading) +void VKGSRender::init_buffers(rsx::framebuffer_creation_context context, bool skip_reading) { //Clear any pending swap requests //TODO: Decide on what to do if we circle back to a new frame before the previous frame waiting on it is still pending @@ -2271,7 +2274,7 @@ void VKGSRender::init_buffers(bool skip_reading) } } - prepare_rtts(); + prepare_rtts(context); if (!skip_reading) { @@ -2300,7 +2303,7 @@ void VKGSRender::open_command_buffer() } -void VKGSRender::prepare_rtts() +void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context) { if (m_draw_fbo && !m_rtts_dirty) return; @@ -2356,22 +2359,22 @@ void VKGSRender::prepare_rtts() zeta_pitch >= required_z_pitch) { LOG_TRACE(RSX, "Framebuffer at 0x%X has aliasing color/depth targets, zeta_pitch = %d, color_pitch=%d", zeta_address, zeta_pitch, surface_pitchs[index]); - m_framebuffer_state_contested = true; - - if (rsx::method_registers.depth_test_enabled() || + if (context == rsx::framebuffer_creation_context::context_clear_depth || + rsx::method_registers.depth_test_enabled() || (!rsx::method_registers.color_write_enabled() && rsx::method_registers.depth_write_enabled()) || !!(rsx::method_registers.shader_control() & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)) - { - // Use address for color data - zeta_address = 0; - break; - } - else { // Use address for depth data // TODO: create a temporary render buffer for this to keep MRT outputs aligned surface_addresses[index] = 0; } + else + { + // Use address for color data + zeta_address = 0; + m_framebuffer_state_contested = true; + break; + } } } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 20ed4eb6ff..48e7dfcb19 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -295,7 +295,7 @@ private: void close_and_submit_command_buffer(const std::vector &semaphores, VkFence fence, VkPipelineStageFlags pipeline_stage_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); void open_command_buffer(); void sync_at_semaphore_release(); - void prepare_rtts(); + void prepare_rtts(rsx::framebuffer_creation_context context); void copy_render_targets_to_dma_location(); void flush_command_queue(bool hard_sync = false); @@ -315,7 +315,7 @@ private: public: bool check_program_status(); void load_program(u32 vertex_count, u32 vertex_base); - void init_buffers(bool skip_reading = false); + void init_buffers(rsx::framebuffer_creation_context context, bool skip_reading = false); void read_buffers(); void write_buffers(); void set_viewport();