From 74696d2e442012e2b4258cf6e941769a523d377a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 26 May 2022 01:50:42 +0300 Subject: [PATCH] gl: Commit to a consistent global state --- rpcs3/Emu/RSX/GL/GLCompute.cpp | 26 ++++---- rpcs3/Emu/RSX/GL/GLCompute.h | 14 ++--- rpcs3/Emu/RSX/GL/GLDraw.cpp | 7 +-- rpcs3/Emu/RSX/GL/GLExecutionState.h | 40 +++++++++++- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 7 ++- rpcs3/Emu/RSX/GL/GLHelpers.cpp | 18 +++--- rpcs3/Emu/RSX/GL/GLHelpers.h | 5 -- rpcs3/Emu/RSX/GL/GLOverlays.cpp | 91 +++++----------------------- rpcs3/Emu/RSX/GL/GLOverlays.h | 6 +- rpcs3/Emu/RSX/GL/GLPresent.cpp | 29 ++++----- rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 4 +- rpcs3/Emu/RSX/GL/GLTextOut.h | 8 +-- rpcs3/Emu/RSX/GL/GLTexture.cpp | 36 +++++------ rpcs3/Emu/RSX/GL/GLTexture.h | 10 +-- rpcs3/Emu/RSX/GL/GLTextureCache.cpp | 4 +- rpcs3/Emu/RSX/GL/GLTextureCache.h | 16 ++--- 16 files changed, 147 insertions(+), 174 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index 369c4bf119..74ee1075ec 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -50,19 +50,15 @@ namespace gl } } - void compute_task::run(u32 invocations_x, u32 invocations_y) + void compute_task::run(gl::command_context& cmd, u32 invocations_x, u32 invocations_y) { - GLint old_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &old_program); - bind_resources(); - m_program.use(); - glDispatchCompute(invocations_x, invocations_y, 1); - glUseProgram(old_program); + cmd->use_program(m_program.id()); + glDispatchCompute(invocations_x, invocations_y, 1); } - void compute_task::run(u32 num_invocations) + void compute_task::run(gl::command_context& cmd, u32 num_invocations) { u32 invocations_x, invocations_y; if (num_invocations <= max_invocations_x) [[likely]] @@ -80,7 +76,7 @@ namespace gl if (num_invocations % invocations_x) invocations_y++; } - run(invocations_x, invocations_y); + run(cmd, invocations_x, invocations_y); } cs_shuffle_base::cs_shuffle_base() @@ -188,7 +184,7 @@ namespace gl m_data->bind_range(gl::buffer::target::ssbo, GL_COMPUTE_BUFFER_SLOT(0), m_data_offset, m_data_length); } - void cs_shuffle_base::run(const gl::buffer* data, u32 data_length, u32 data_offset) + void cs_shuffle_base::run(gl::command_context& cmd, const gl::buffer* data, u32 data_length, u32 data_offset) { m_data = data; m_data_offset = data_offset; @@ -205,7 +201,7 @@ namespace gl "Required=%d bytes, Available=%d bytes", num_bytes_to_process, data->size()); } - compute_task::run(num_invocations); + compute_task::run(cmd, num_invocations); } cs_shuffle_d32fx8_to_x8d24f::cs_shuffle_d32fx8_to_x8d24f() @@ -232,7 +228,7 @@ namespace gl m_data->bind_range(gl::buffer::target::ssbo, GL_COMPUTE_BUFFER_SLOT(0), m_data_offset, m_ssbo_length); } - void cs_shuffle_d32fx8_to_x8d24f::run(const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels) + void cs_shuffle_d32fx8_to_x8d24f::run(gl::command_context& cmd, const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels) { u32 data_offset; if (src_offset > dst_offset) @@ -248,7 +244,7 @@ namespace gl m_program.uniforms["in_ptr"] = src_offset - data_offset; m_program.uniforms["out_ptr"] = dst_offset - data_offset; - cs_shuffle_base::run(data, num_texels * 4, data_offset); + cs_shuffle_base::run(cmd, data, num_texels * 4, data_offset); } cs_shuffle_x8d24f_to_d32fx8::cs_shuffle_x8d24f_to_d32fx8() @@ -276,7 +272,7 @@ namespace gl m_data->bind_range(gl::buffer::target::ssbo, GL_COMPUTE_BUFFER_SLOT(0), m_data_offset, m_ssbo_length); } - void cs_shuffle_x8d24f_to_d32fx8::run(const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels) + void cs_shuffle_x8d24f_to_d32fx8::run(gl::command_context& cmd, const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels) { u32 data_offset; if (src_offset > dst_offset) @@ -292,6 +288,6 @@ namespace gl m_program.uniforms["in_ptr"] = src_offset - data_offset; m_program.uniforms["out_ptr"] = dst_offset - data_offset; - cs_shuffle_base::run(data, num_texels * 4, data_offset); + cs_shuffle_base::run(cmd, data, num_texels * 4, data_offset); } } diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index de63ce477c..6bef8e33ed 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.h +++ b/rpcs3/Emu/RSX/GL/GLCompute.h @@ -26,8 +26,8 @@ namespace gl virtual void bind_resources() {} - void run(u32 invocations_x, u32 invocations_y); - void run(u32 num_invocations); + void run(gl::command_context& cmd, u32 invocations_x, u32 invocations_y); + void run(gl::command_context& cmd, u32 num_invocations); }; struct cs_shuffle_base : compute_task @@ -45,7 +45,7 @@ namespace gl void bind_resources() override; - void run(const gl::buffer* data, u32 data_length, u32 data_offset = 0); + void run(gl::command_context& cmd, const gl::buffer* data, u32 data_length, u32 data_offset = 0); }; struct cs_shuffle_16 : cs_shuffle_base @@ -83,7 +83,7 @@ namespace gl void bind_resources() override; - void run(const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels); + void run(gl::command_context& cmd, const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels); }; struct cs_shuffle_x8d24f_to_d32fx8 : cs_shuffle_base @@ -94,7 +94,7 @@ namespace gl void bind_resources() override; - void run(const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels); + void run(gl::command_context& cmd, const gl::buffer* data, u32 src_offset, u32 dst_offset, u32 num_texels); }; @@ -204,7 +204,7 @@ namespace gl m_data->bind_range(gl::buffer::target::ssbo, GL_COMPUTE_BUFFER_SLOT(0), m_data_offset, m_ssbo_length); } - void run(const gl::buffer* data, u32 src_offset, u32 src_length, u32 dst_offset) + void run(gl::command_context& cmd, const gl::buffer* data, u32 src_offset, u32 src_length, u32 dst_offset) { u32 data_offset; if (src_offset > dst_offset) @@ -222,7 +222,7 @@ namespace gl m_program.uniforms["in_ptr"] = src_offset - data_offset; m_program.uniforms["out_ptr"] = dst_offset - data_offset; - cs_shuffle_base::run(data, src_length, data_offset); + cs_shuffle_base::run(cmd, data, src_length, data_offset); } }; diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 063f9ab1d6..ebd4b97224 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -137,6 +137,8 @@ void GLGSRender::update_draw_state() { m_profiler.start(); + gl_state.enable(GL_SCISSOR_TEST); + for (int index = 0; index < m_rtts.get_color_surface_count(); ++index) { bool color_mask_b = rsx::method_registers.color_mask_b(index); @@ -656,8 +658,6 @@ void GLGSRender::end() m_gl_texture_cache.release_uncached_temporary_subresources(); m_frame_stats.textures_upload_time += m_profiler.duration(); - gl_state.enable(GL_FALSE, GL_SCISSOR_TEST); - gl::command_context cmd{ gl_state }; if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil)) ds->write_barrier(cmd); @@ -669,9 +669,6 @@ void GLGSRender::end() } } - // Unconditionally enable stencil test if it was disabled before - gl_state.enable(GL_TRUE, GL_SCISSOR_TEST); - update_draw_state(); if (g_cfg.video.debug_output) diff --git a/rpcs3/Emu/RSX/GL/GLExecutionState.h b/rpcs3/Emu/RSX/GL/GLExecutionState.h index 34b40c4b62..41c06c8d2d 100644 --- a/rpcs3/Emu/RSX/GL/GLExecutionState.h +++ b/rpcs3/Emu/RSX/GL/GLExecutionState.h @@ -232,6 +232,8 @@ namespace gl std::unordered_map properties = {}; std::unordered_map> indexed_properties = {}; + GLuint current_program = GL_NONE; + bool enable(u32 test, GLenum cap) { auto found = properties.find(cap); @@ -274,6 +276,26 @@ namespace gl return !!test; } + bool enable(GLenum cap) + { + return enable(GL_TRUE, cap); + } + + bool enablei(GLenum cap, u32 index) + { + return enablei(GL_TRUE, cap, index); + } + + bool disable(GLenum cap) + { + return enable(GL_FALSE, cap); + } + + bool disablei(GLenum cap, u32 index) + { + return enablei(GL_FALSE, cap, index); + } + inline bool test_property(GLenum property, u32 test) const { auto found = properties.find(property); @@ -467,12 +489,24 @@ namespace gl properties[GL_POLYGON_OFFSET_FACTOR] = _factor; } } + + void use_program(GLuint program) + { + if (current_program == program) + { + return; + } + + current_program = program; + glUseProgram(program); + } }; - struct command_context + class command_context { driver_state* drv; + public: command_context() : drv(nullptr) {} @@ -480,5 +514,9 @@ namespace gl command_context(driver_state& drv_) : drv(&drv_) {} + + driver_state* operator -> () { + return drv; + } }; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 83ae9dcf2d..bae819394e 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -662,6 +662,11 @@ void GLGSRender::clear_surface(u32 arg) m_rtts.on_write({ update_color, update_color, update_color, update_color }, update_z); } + if (!full_frame) + { + gl_state.enable(GL_SCISSOR_TEST); + } + glClear(mask); } @@ -762,7 +767,7 @@ void GLGSRender::load_program_env() const bool update_instruction_buffers = (!!m_interpreter_state && m_shader_interpreter.is_interpreter(m_program)); const bool update_raster_env = (rsx::method_registers.polygon_stipple_enabled() && !!(m_graphics_state & rsx::pipeline_state::polygon_stipple_pattern_dirty)); - m_program->use(); + gl_state.use_program(m_program->id()); if (manually_flush_ring_buffers) { diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.cpp b/rpcs3/Emu/RSX/GL/GLHelpers.cpp index ebbeb15e1f..a6fa97b252 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.cpp +++ b/rpcs3/Emu/RSX/GL/GLHelpers.cpp @@ -503,7 +503,7 @@ namespace gl { const coord3i src_region = { { src_rect.x1, src_rect.y1, 0 }, { src_rect.width(), src_rect.height(), 1 } }; const coord3i dst_region = { { dst_rect.x1, dst_rect.y1, 0 }, { dst_rect.width(), dst_rect.height(), 1 } }; - gl::copy_typeless(dst, src, static_cast(dst_region), static_cast(src_region)); + gl::copy_typeless(cmd, dst, src, static_cast(dst_region), static_cast(src_region)); } else { @@ -526,7 +526,7 @@ namespace gl { const u16 internal_width = static_cast(src->width() * xfer_info.src_scaling_hint); typeless_src = std::make_unique(GL_TEXTURE_2D, internal_width, src->height(), 1, 1, internal_fmt); - copy_typeless(typeless_src.get(), src); + copy_typeless(cmd, typeless_src.get(), src); real_src = typeless_src.get(); src_rect.x1 = static_cast(src_rect.x1 * xfer_info.src_scaling_hint); @@ -544,7 +544,7 @@ namespace gl { const auto internal_width = static_cast(dst->width() * xfer_info.dst_scaling_hint); typeless_dst = std::make_unique(GL_TEXTURE_2D, internal_width, dst->height(), 1, 1, internal_fmt); - copy_typeless(typeless_dst.get(), dst); + copy_typeless(cmd, typeless_dst.get(), dst); real_dst = typeless_dst.get(); dst_rect.x1 = static_cast(dst_rect.x1 * xfer_info.dst_scaling_hint); @@ -587,7 +587,7 @@ namespace gl target = gl::buffers::color; } - cmd.drv->enable(GL_FALSE, GL_SCISSOR_TEST); + cmd->disable(GL_SCISSOR_TEST); save_binding_state saved; @@ -619,7 +619,7 @@ namespace gl if (xfer_info.dst_is_typeless) { // Transfer contents from typeless dst back to original dst - copy_typeless(dst, typeless_dst.get()); + copy_typeless(cmd, dst, typeless_dst.get()); } } @@ -631,8 +631,8 @@ namespace gl glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst->id(), 0); blit_dst.check(); - cmd.drv->clear_color(color); - cmd.drv->color_maski(0, true, true, true, true); + cmd->clear_color(color); + cmd->color_maski(0, true, true, true, true); glClear(GL_COLOR_BUFFER_BIT); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, GL_NONE, 0); @@ -665,8 +665,8 @@ namespace gl glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst->id(), 0); blit_dst.check(); - cmd.drv->depth_mask(GL_TRUE); - cmd.drv->stencil_mask(0xFF); + cmd->depth_mask(GL_TRUE); + cmd->stencil_mask(0xFF); glClear(clear_mask); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0); diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index ae61e917b1..7dd27e3989 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -2591,11 +2591,6 @@ public: return{ static_cast(id) }; } - void use() - { - glUseProgram(m_id); - } - void link(std::function init_func = {}) { glLinkProgram(m_id); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 3d28e263cb..22426d51d9 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -69,7 +69,7 @@ namespace gl glBindVertexArray(old_vao); } - void overlay_pass::run(const areau& region, GLuint target_texture, bool depth_target, bool use_blending) + void overlay_pass::run(gl::command_context& cmd, const areau& region, GLuint target_texture, bool depth_target, bool use_blending) { if (!compiled) { @@ -77,19 +77,8 @@ namespace gl return; } - GLint program; GLint old_fbo; - GLint depth_func; GLint viewport[4]; - GLboolean color_writes[4]; - GLboolean depth_write; - - GLint blend_src_rgb; - GLint blend_src_a; - GLint blend_dst_rgb; - GLint blend_dst_a; - GLint blend_eq_a; - GLint blend_eq_rgb; if (target_texture) { @@ -111,57 +100,32 @@ namespace gl if (!target_texture || glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - // Push rasterizer state - glGetIntegerv(GL_VIEWPORT, viewport); - glGetBooleanv(GL_COLOR_WRITEMASK, color_writes); - glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_write); - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - glGetIntegerv(GL_DEPTH_FUNC, &depth_func); - - GLboolean scissor_enabled = glIsEnabled(GL_SCISSOR_TEST); - GLboolean depth_test_enabled = glIsEnabled(GL_DEPTH_TEST); - GLboolean cull_face_enabled = glIsEnabled(GL_CULL_FACE); - GLboolean blend_enabled = glIsEnabledi(GL_BLEND, 0); - GLboolean stencil_test_enabled = glIsEnabled(GL_STENCIL_TEST); - - if (use_blending) - { - glGetIntegerv(GL_BLEND_SRC_RGB, &blend_src_rgb); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &blend_src_a); - glGetIntegerv(GL_BLEND_DST_RGB, &blend_dst_rgb); - glGetIntegerv(GL_BLEND_DST_ALPHA, &blend_dst_a); - glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend_eq_rgb); - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blend_eq_a); - } - // Set initial state glViewport(region.x1, region.y1, region.width(), region.height()); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDepthMask(depth_target ? GL_TRUE : GL_FALSE); + cmd->color_maski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + cmd->depth_mask(depth_target ? GL_TRUE : GL_FALSE); // Disabling depth test will also disable depth writes which is not desired - glDepthFunc(GL_ALWAYS); - glEnable(GL_DEPTH_TEST); + cmd->depth_func(GL_ALWAYS); + cmd->enable(GL_DEPTH_TEST); - if (scissor_enabled) glDisable(GL_SCISSOR_TEST); - if (cull_face_enabled) glDisable(GL_CULL_FACE); - if (stencil_test_enabled) glDisable(GL_STENCIL_TEST); + cmd->disable(GL_SCISSOR_TEST); + cmd->disable(GL_CULL_FACE); + cmd->disable(GL_STENCIL_TEST); if (use_blending) { - if (!blend_enabled) - glEnablei(GL_BLEND, 0); - + cmd->enablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); } - else if (blend_enabled) + else { - glDisablei(GL_BLEND, 0); + cmd->disablei(GL_BLEND, 0); } // Render - program_handle.use(); + cmd->use_program(program_handle.id()); on_load(); bind_resources(); emit_geometry(); @@ -177,30 +141,7 @@ namespace gl glBindFramebuffer(GL_FRAMEBUFFER, old_fbo); } - glUseProgram(program); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - glColorMask(color_writes[0], color_writes[1], color_writes[2], color_writes[3]); - glDepthMask(depth_write); - glDepthFunc(depth_func); - - if (!depth_test_enabled) glDisable(GL_DEPTH_TEST); - if (scissor_enabled) glEnable(GL_SCISSOR_TEST); - if (cull_face_enabled) glEnable(GL_CULL_FACE); - if (stencil_test_enabled) glEnable(GL_STENCIL_TEST); - - if (use_blending) - { - if (!blend_enabled) - glDisablei(GL_BLEND, 0); - - glBlendFuncSeparate(blend_src_rgb, blend_dst_rgb, blend_src_a, blend_dst_a); - glBlendEquationSeparate(blend_eq_rgb, blend_eq_a); - } - else if (blend_enabled) - { - glEnablei(GL_BLEND, 0); - } } else { @@ -508,7 +449,7 @@ namespace gl } } - void ui_overlay_renderer::run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui) + void ui_overlay_renderer::run(gl::command_context& cmd_, const areau& viewport, GLuint target, rsx::overlays::overlay& ui) { program_handle.uniforms["viewport"] = color4f(static_cast(viewport.width()), static_cast(viewport.height()), static_cast(viewport.x1), static_cast(viewport.y1)); program_handle.uniforms["ui_scale"] = color4f(static_cast(ui.virtual_width), static_cast(ui.virtual_height), 1.f, 1.f); @@ -561,7 +502,7 @@ namespace gl program_handle.uniforms["blur_strength"] = static_cast(cmd.config.blur_strength); program_handle.uniforms["clip_region"] = static_cast(cmd.config.clip_region); program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect; - overlay_pass::run(viewport, target, false, true); + overlay_pass::run(cmd_, viewport, target, false, true); } ui.update(); @@ -628,7 +569,7 @@ namespace gl input_filter = GL_LINEAR; } - void video_out_calibration_pass::run(const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d) + void video_out_calibration_pass::run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d) { program_handle.uniforms["gamma"] = gamma; program_handle.uniforms["limit_range"] = limited_rgb + 0; @@ -641,6 +582,6 @@ namespace gl saved_sampler_state saved2(30, m_sampler); glBindTexture(GL_TEXTURE_2D, source[1]); - overlay_pass::run(viewport, GL_NONE, false, false); + overlay_pass::run(cmd, viewport, GL_NONE, false, false); } } diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 38dc655125..bd8b69b4f3 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -69,7 +69,7 @@ namespace gl virtual void emit_geometry(); - void run(const areau& region, GLuint target_texture, bool depth_target, bool use_blending = false); + void run(gl::command_context& cmd, const areau& region, GLuint target_texture, bool depth_target, bool use_blending = false); }; struct ui_overlay_renderer : public overlay_pass @@ -99,13 +99,13 @@ namespace gl void emit_geometry() override; - void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui); + void run(gl::command_context& cmd, const areau& viewport, GLuint target, rsx::overlays::overlay& ui); }; struct video_out_calibration_pass : public overlay_pass { video_out_calibration_pass(); - void run(const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d); + void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array& source, f32 gamma, bool limited_rgb, bool _3d); }; } diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index d16855bd8c..0840419ffb 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -123,6 +123,8 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) return; } + gl::command_context cmd{ gl_state }; + u32 buffer_width = display_buffers[info.buffer].width; u32 buffer_height = display_buffers[info.buffer].height; u32 buffer_pitch = display_buffers[info.buffer].pitch; @@ -154,7 +156,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) } // Disable scissor test (affects blit, clear, etc) - gl_state.enable(GL_FALSE, GL_SCISSOR_TEST); + gl_state.disable(GL_SCISSOR_TEST); // Enable drawing to window backbuffer gl::screen.bind(); @@ -266,7 +268,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const rsx::simple_array images{ image_to_flip, image_to_flip2 }; gl::screen.bind(); - m_video_output_pass.run(areau(aspect_ratio), images, gamma, limited_range, avconfig._3d); + m_video_output_pass.run(cmd, areau(aspect_ratio), images, gamma, limited_range, avconfig._3d); } } @@ -298,7 +300,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) for (const auto& view : m_overlay_manager->get_views()) { - m_ui_renderer.run(areau(aspect_ratio), 0, *view.get()); + m_ui_renderer.run(cmd, areau(aspect_ratio), 0, *view.get()); } } } @@ -319,12 +321,12 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) m_text_printer.set_scale(m_frame->client_device_pixel_ratio()); - m_text_printer.print_text(4, 0, width, height, fmt::format("RSX Load: %3d%%", get_load())); - m_text_printer.print_text(4, 18, width, height, fmt::format("draw calls: %16d", info.stats.draw_calls)); - m_text_printer.print_text(4, 36, width, height, fmt::format("draw call setup: %11dus", info.stats.setup_time)); - m_text_printer.print_text(4, 54, width, height, fmt::format("vertex upload time: %8dus", info.stats.vertex_upload_time)); - m_text_printer.print_text(4, 72, width, height, fmt::format("textures upload time: %6dus", info.stats.textures_upload_time)); - m_text_printer.print_text(4, 90, width, height, fmt::format("draw call execution: %7dus", info.stats.draw_exec_time)); + m_text_printer.print_text(cmd, 4, 0, width, height, fmt::format("RSX Load: %3d%%", get_load())); + m_text_printer.print_text(cmd, 4, 18, width, height, fmt::format("draw calls: %16d", info.stats.draw_calls)); + m_text_printer.print_text(cmd, 4, 36, width, height, fmt::format("draw call setup: %11dus", info.stats.setup_time)); + m_text_printer.print_text(cmd, 4, 54, width, height, fmt::format("vertex upload time: %8dus", info.stats.vertex_upload_time)); + m_text_printer.print_text(cmd, 4, 72, width, height, fmt::format("textures upload time: %6dus", info.stats.textures_upload_time)); + m_text_printer.print_text(cmd, 4, 90, width, height, fmt::format("draw call execution: %7dus", info.stats.draw_exec_time)); const auto num_dirty_textures = m_gl_texture_cache.get_unreleased_textures_count(); const auto texture_memory_size = m_gl_texture_cache.get_texture_memory_in_use() / (1024 * 1024); @@ -337,10 +339,10 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const auto num_texture_upload = m_gl_texture_cache.get_texture_upload_calls_this_frame(); const auto num_texture_upload_miss = m_gl_texture_cache.get_texture_upload_misses_this_frame(); const auto texture_upload_miss_ratio = m_gl_texture_cache.get_texture_upload_miss_percentage(); - m_text_printer.print_text(4, 126, width, height, fmt::format("Unreleased textures: %7d", num_dirty_textures)); - m_text_printer.print_text(4, 144, width, height, fmt::format("Texture memory: %12dM", texture_memory_size)); - m_text_printer.print_text(4, 162, width, height, fmt::format("Flush requests: %12d = %2d (%3d%%) hard faults, %2d unavoidable, %2d misprediction(s), %2d speculation(s)", num_flushes, num_misses, cache_miss_ratio, num_unavoidable, num_mispredict, num_speculate)); - m_text_printer.print_text(4, 180, width, height, fmt::format("Texture uploads: %15u (%u from CPU - %02u%%)", num_texture_upload, num_texture_upload_miss, texture_upload_miss_ratio)); + m_text_printer.print_text(cmd, 4, 126, width, height, fmt::format("Unreleased textures: %7d", num_dirty_textures)); + m_text_printer.print_text(cmd, 4, 144, width, height, fmt::format("Texture memory: %12dM", texture_memory_size)); + m_text_printer.print_text(cmd, 4, 162, width, height, fmt::format("Flush requests: %12d = %2d (%3d%%) hard faults, %2d unavoidable, %2d misprediction(s), %2d speculation(s)", num_flushes, num_misses, cache_miss_ratio, num_unavoidable, num_mispredict, num_speculate)); + m_text_printer.print_text(cmd, 4, 180, width, height, fmt::format("Texture uploads: %15u (%u from CPU - %02u%%)", num_texture_upload, num_texture_upload_miss, texture_upload_miss_ratio)); } if (gl::debug::g_vis_texture) @@ -374,7 +376,6 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) m_gl_texture_cache.on_frame_end(); m_vertex_cache->purge(); - gl::command_context cmd{ gl_state }; auto removed_textures = m_rtts.free_invalidated(cmd); m_framebuffer_cache.remove_if([&](auto& fbo) { diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 0dff091cd3..b5bae43d64 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -425,12 +425,12 @@ void gl::render_target::load_memory(gl::command_context& cmd) // TODO: MSAA support if (g_cfg.video.resolution_scale_percent == 100 && spp == 1) [[likely]] { - gl::upload_texture(this, get_gcm_format(), is_swizzled, { subres }); + gl::upload_texture(cmd, this, get_gcm_format(), is_swizzled, { subres }); } else { auto tmp = std::make_unique(GL_TEXTURE_2D, subres.width_in_block, subres.height_in_block, 1, 1, static_cast(get_internal_format()), format_class()); - gl::upload_texture(tmp.get(), get_gcm_format(), is_swizzled, { subres }); + gl::upload_texture(cmd, tmp.get(), get_gcm_format(), is_swizzled, { subres }); gl::g_hw_blitter->scale_image(cmd, tmp.get(), this, { 0, 0, subres.width_in_block, subres.height_in_block }, diff --git a/rpcs3/Emu/RSX/GL/GLTextOut.h b/rpcs3/Emu/RSX/GL/GLTextOut.h index 28d94e7f91..686008875e 100644 --- a/rpcs3/Emu/RSX/GL/GLTextOut.h +++ b/rpcs3/Emu/RSX/GL/GLTextOut.h @@ -69,11 +69,11 @@ namespace gl m_program.link(); } - void load_program(float scale_x, float scale_y, float *offsets, usz nb_offsets, color4f color) + void load_program(gl::command_context& cmd, float scale_x, float scale_y, float *offsets, usz nb_offsets, color4f color) { float scale[] = { scale_x, scale_y }; - m_program.use(); + cmd->use_program(m_program.id()); m_program.uniforms["draw_color"] = color; glProgramUniform2fv(m_program.id(), m_program.uniforms["offsets"].location(), static_cast(nb_offsets), offsets); @@ -128,7 +128,7 @@ namespace gl return enabled; } - void print_text(int x, int y, int target_w, int target_h, const std::string &text, color4f color = { 0.3f, 1.f, 0.3f, 1.f }) + void print_text(gl::command_context& cmd, int x, int y, int target_w, int target_h, const std::string &text, color4f color = { 0.3f, 1.f, 0.3f, 1.f }) { if (!enabled) return; @@ -186,7 +186,7 @@ namespace gl int old_vao; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao); - load_program(scale_x, scale_y, shader_offsets.data(), counts.size(), color); + load_program(cmd, scale_x, scale_y, shader_offsets.data(), counts.size(), color); m_vao.bind(); diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 4dec07ed88..4d99bbff8e 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -442,7 +442,7 @@ namespace gl } } - void* copy_image_to_buffer(const pixel_buffer_layout& pack_info, const gl::texture* src, gl::buffer* dst, + void* copy_image_to_buffer(gl::command_context& cmd, const pixel_buffer_layout& pack_info, const gl::texture* src, gl::buffer* dst, const int src_level, const coord3u& src_region, image_memory_requirements* mem_info) { auto initialize_scratch_mem = [&]() @@ -466,7 +466,7 @@ namespace gl initialize_scratch_mem(); if (auto job = get_trivial_transform_job(pack_info)) { - job->run(dst, static_cast(mem_info->image_size_in_bytes)); + job->run(cmd, dst, static_cast(mem_info->image_size_in_bytes)); } } else if (pack_info.type == GL_FLOAT) @@ -475,7 +475,7 @@ namespace gl mem_info->memory_required = (mem_info->image_size_in_texels * 6); initialize_scratch_mem(); - get_compute_task>()->run(dst, 0, + get_compute_task>()->run(cmd, dst, 0, static_cast(mem_info->image_size_in_bytes), static_cast(mem_info->image_size_in_bytes)); result = reinterpret_cast(mem_info->image_size_in_bytes); } @@ -485,7 +485,7 @@ namespace gl mem_info->memory_required = (mem_info->image_size_in_texels * 12); initialize_scratch_mem(); - get_compute_task()->run(dst, 0, + get_compute_task()->run(cmd, dst, 0, static_cast(mem_info->image_size_in_bytes), static_cast(mem_info->image_size_in_texels)); result = reinterpret_cast(mem_info->image_size_in_bytes); } @@ -498,7 +498,7 @@ namespace gl return result; } - void copy_buffer_to_image(const pixel_buffer_layout& unpack_info, gl::buffer* src, gl::texture* dst, + void copy_buffer_to_image(gl::command_context& cmd, const pixel_buffer_layout& unpack_info, gl::buffer* src, gl::texture* dst, const void* src_offset, const int dst_level, const coord3u& dst_region, image_memory_requirements* mem_info) { buffer scratch_mem; @@ -537,7 +537,7 @@ namespace gl { if (auto job = get_trivial_transform_job(unpack_info)) { - job->run(src, static_cast(mem_info->image_size_in_bytes), in_offset); + job->run(cmd, src, static_cast(mem_info->image_size_in_bytes), in_offset); } else { @@ -551,18 +551,18 @@ namespace gl if (unpack_info.swap_bytes) { - get_compute_task>()->run(transfer_buf, in_offset, static_cast(mem_info->image_size_in_bytes), out_offset); + get_compute_task>()->run(cmd, transfer_buf, in_offset, static_cast(mem_info->image_size_in_bytes), out_offset); } else { - get_compute_task>()->run(transfer_buf, in_offset, static_cast(mem_info->image_size_in_bytes), out_offset); + get_compute_task>()->run(cmd, transfer_buf, in_offset, static_cast(mem_info->image_size_in_bytes), out_offset); } } else if (unpack_info.type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) { mem_info->memory_required = (mem_info->image_size_in_texels * 8); initialize_scratch_mem(); - get_compute_task()->run(transfer_buf, in_offset, out_offset, static_cast(mem_info->image_size_in_texels)); + get_compute_task()->run(cmd, transfer_buf, in_offset, out_offset, static_cast(mem_info->image_size_in_texels)); } else { @@ -593,7 +593,7 @@ namespace gl return new gl::viewable_image(target, width, height, depth, mipmaps, internal_format, format_class); } - void fill_texture(texture* dst, int format, + void fill_texture(gl::command_context& cmd, texture* dst, int format, const std::vector &input_layouts, bool is_swizzled, GLenum gl_format, GLenum gl_type, std::vector& staging_buffer) { @@ -735,7 +735,7 @@ namespace gl mem_info.memory_required = 0; // 4. Dispatch compute routines - copy_buffer_to_image(mem_layout, &compute_scratch_mem, dst, nullptr, layout.level, region, & mem_info); + copy_buffer_to_image(cmd, mem_layout, &compute_scratch_mem, dst, nullptr, layout.level, region, & mem_info); } else { @@ -790,7 +790,7 @@ namespace gl return remap_values; } - void upload_texture(texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout) + void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout) { // Calculate staging buffer size std::vector data_upload_buf; @@ -812,7 +812,7 @@ namespace gl const auto format_type = get_format_type(gcm_format); const GLenum gl_format = std::get<0>(format_type); const GLenum gl_type = std::get<1>(format_type); - fill_texture(dst, gcm_format, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf); + fill_texture(cmd, dst, gcm_format, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf); } u32 get_format_texel_width(GLenum format) @@ -894,7 +894,7 @@ namespace gl return formats_are_bitcast_compatible(static_cast(texture1->get_internal_format()), static_cast(texture2->get_internal_format())); } - void copy_typeless(texture * dst, const texture * src, const coord3u& dst_region, const coord3u& src_region) + void copy_typeless(gl::command_context& cmd, texture * dst, const texture * src, const coord3u& dst_region, const coord3u& src_region) { const auto src_bpp = src->pitch() / src->width(); const auto dst_bpp = dst->pitch() / dst->width(); @@ -934,8 +934,8 @@ namespace gl unpack_info.swap_bytes = false; } - void* data_ptr = copy_image_to_buffer(pack_info, src, &g_typeless_transfer_buffer, 0, src_region, &src_mem); - copy_buffer_to_image(unpack_info, &g_typeless_transfer_buffer, dst, data_ptr, 0, dst_region, &dst_mem); + void* data_ptr = copy_image_to_buffer(cmd, pack_info, src, &g_typeless_transfer_buffer, 0, src_region, &src_mem); + copy_buffer_to_image(cmd, unpack_info, &g_typeless_transfer_buffer, dst, data_ptr, 0, dst_region, &dst_mem); // Cleanup // NOTE: glBindBufferRange also binds the buffer to the old-school target. @@ -1022,10 +1022,10 @@ namespace gl } } - void copy_typeless(texture* dst, const texture* src) + void copy_typeless(gl::command_context& cmd, texture* dst, const texture* src) { const coord3u src_area = { {}, src->size3D() }; const coord3u dst_area = { {}, dst->size3D() }; - copy_typeless(dst, src, dst_area, src_area); + copy_typeless(cmd, dst, src, dst_area, src_area); } } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index e0e2747581..4a8b605533 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -41,16 +41,16 @@ namespace gl viewable_image* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type); bool formats_are_bitcast_compatible(const texture* texture1, const texture* texture2); - void copy_typeless(texture* dst, const texture* src, const coord3u& dst_region, const coord3u& src_region); - void copy_typeless(texture* dst, const texture* src); + void copy_typeless(gl::command_context& cmd, texture* dst, const texture* src, const coord3u& dst_region, const coord3u& src_region); + void copy_typeless(gl::command_context& cmd, texture* dst, const texture* src); - void* copy_image_to_buffer(const pixel_buffer_layout& pack_info, const gl::texture* src, gl::buffer* dst, + void* copy_image_to_buffer(gl::command_context& cmd, const pixel_buffer_layout& pack_info, const gl::texture* src, gl::buffer* dst, const int src_level, const coord3u& src_region, image_memory_requirements* mem_info); - void copy_buffer_to_image(const pixel_buffer_layout& unpack_info, gl::buffer* src, gl::texture* dst, + void copy_buffer_to_image(gl::command_context& cmd, const pixel_buffer_layout& unpack_info, gl::buffer* src, gl::texture* dst, const void* src_offset, const int dst_level, const coord3u& dst_region, image_memory_requirements* mem_info); - void upload_texture(texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout); + void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout); class sampler_state { diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index 35ce75653e..c52ef20f34 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -179,14 +179,14 @@ namespace gl // Combine the two transfers into one const coord3u src_region = { { src_x, src_y, 0 }, { src_w, src_h, 1 } }; const coord3u dst_region = { { slice.dst_x, slice.dst_y, slice.dst_z }, { slice.dst_w, slice.dst_h, 1 } }; - gl::copy_typeless(dst_image, slice.src, dst_region, src_region); + gl::copy_typeless(cmd, dst_image, slice.src, dst_region, src_region); continue; } const coord3u src_region = { { src_x, src_y, 0 }, { src_w, src_h, 1 } }; const coord3u dst_region = { { src_x2, src_y, 0 }, { src_w2, src_h, 1 } }; - gl::copy_typeless(src_image, slice.src, dst_region, src_region); + gl::copy_typeless(cmd, src_image, slice.src, dst_region, src_region); src_x = src_x2; src_w = src_w2; diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 69d80f0307..c5540dcd8f 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -148,7 +148,7 @@ namespace gl } } - void dma_transfer(gl::command_context& /*cmd*/, gl::texture* src, const areai& /*src_area*/, const utils::address_range& /*valid_range*/, u32 pitch) + void dma_transfer(gl::command_context& cmd, gl::texture* src, const areai& /*src_area*/, const utils::address_range& /*valid_range*/, u32 pitch) { init_buffer(src); glGetError(); @@ -193,7 +193,7 @@ namespace gl mem_info.image_size_in_bytes *= 2; } - void* out_offset = copy_image_to_buffer(pack_info, src, &scratch_mem, 0, { {}, src->size3D() }, &mem_info); + void* out_offset = copy_image_to_buffer(cmd, pack_info, src, &scratch_mem, 0, { {}, src->size3D() }, &mem_info); glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); @@ -562,13 +562,13 @@ namespace gl protected: - gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture** src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, + gl::texture_view* create_temporary_subresource_view(gl::command_context& cmd, gl::texture** src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const rsx::texture_channel_remap_t& remap_vector) override { return create_temporary_subresource_impl(cmd, *src, GL_NONE, GL_TEXTURE_2D, gcm_format, x, y, w, h, 1, 1, remap_vector, true); } - gl::texture_view* create_temporary_subresource_view(gl::command_context &cmd, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, + gl::texture_view* create_temporary_subresource_view(gl::command_context& cmd, gl::texture* src, u32 gcm_format, u16 x, u16 y, u16 w, u16 h, const rsx::texture_channel_remap_t& remap_vector) override { return create_temporary_subresource_impl(cmd, src, static_cast(src->get_internal_format()), @@ -641,7 +641,7 @@ namespace gl copy_transfer_regions_impl(cmd, dst->image(), region); } - cached_texture_section* create_new_texture(gl::command_context &cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 pitch, + cached_texture_section* create_new_texture(gl::command_context& cmd, const utils::address_range &rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 pitch, u32 gcm_format, rsx::texture_upload_context context, rsx::texture_dimension_extended type, bool swizzled, rsx::component_order swizzle_flags, rsx::flags32_t /*flags*/) override { const rsx::image_section_attributes_t search_desc = { .gcm_format = gcm_format, .width = width, .height = height, .depth = depth, .mipmaps = mipmaps }; @@ -762,13 +762,13 @@ namespace gl return &cached; } - cached_texture_section* upload_image_from_cpu(gl::command_context &cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 pitch, u32 gcm_format, + cached_texture_section* upload_image_from_cpu(gl::command_context& cmd, const utils::address_range& rsx_range, u16 width, u16 height, u16 depth, u16 mipmaps, u32 pitch, u32 gcm_format, rsx::texture_upload_context context, const std::vector& subresource_layout, rsx::texture_dimension_extended type, bool input_swizzled) override { auto section = create_new_texture(cmd, rsx_range, width, height, depth, mipmaps, pitch, gcm_format, context, type, input_swizzled, rsx::component_order::default_, 0); - gl::upload_texture(section->get_raw_texture(), gcm_format, input_swizzled, subresource_layout); + gl::upload_texture(cmd, section->get_raw_texture(), gcm_format, input_swizzled, subresource_layout); section->last_write_tag = rsx::get_shared_tag(); return section; @@ -897,7 +897,7 @@ namespace gl baseclass::on_frame_end(); } - bool blit(gl::command_context &cmd, rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool linear_interpolate, gl_render_targets& m_rtts) + bool blit(gl::command_context& cmd, rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool linear_interpolate, gl_render_targets& m_rtts) { auto result = upload_scaled_image(src, dst, linear_interpolate, cmd, m_rtts, m_hw_blitter);