diff --git a/Utilities/geometry.h b/Utilities/geometry.h index 6435afaa14..e11ebd2a98 100644 --- a/Utilities/geometry.h +++ b/Utilities/geometry.h @@ -664,7 +664,8 @@ struct area_base { } - constexpr area_base(const coord_base& coord) : x1{ coord.x }, x2{ coord.x + coord.width }, y1{ coord.y }, y2{ coord.y + coord.height } + template + constexpr area_base(const coord_base& coord) : x1{ T(coord.x) }, x2{ T(coord.x + coord.width) }, y1{ T(coord.y) }, y2{ T(coord.y + coord.height) } { } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 1a8569d6fc..411120903c 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1589,33 +1589,33 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) gl::screen.bind(); gl::screen.clear(gl::buffers::color); + // Calculate blit coordinates + coordi aspect_ratio; + sizei csize(m_frame->client_width(), m_frame->client_height()); + sizei new_size = csize; + + if (!g_cfg.video.stretch_to_display_area) + { + const double aq = (double)buffer_width / buffer_height; + const double rq = (double)new_size.width / new_size.height; + const double q = aq / rq; + + if (q > 1.0) + { + new_size.height = int(new_size.height / q); + aspect_ratio.y = (csize.height - new_size.height) / 2; + } + else if (q < 1.0) + { + new_size.width = int(new_size.width * q); + aspect_ratio.x = (csize.width - new_size.width) / 2; + } + } + + aspect_ratio.size = new_size; + if ((u32)info.buffer < display_buffers_count && buffer_width && buffer_height) { - // Calculate blit coordinates - coordi aspect_ratio; - sizei csize(m_frame->client_width(), m_frame->client_height()); - sizei new_size = csize; - - if (!g_cfg.video.stretch_to_display_area) - { - const double aq = (double)buffer_width / buffer_height; - const double rq = (double)new_size.width / new_size.height; - const double q = aq / rq; - - if (q > 1.0) - { - new_size.height = int(new_size.height / q); - aspect_ratio.y = (csize.height - new_size.height) / 2; - } - else if (q < 1.0) - { - new_size.width = int(new_size.width * q); - aspect_ratio.x = (csize.width - new_size.width) / 2; - } - } - - aspect_ratio.size = new_size; - // Find the source image const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL); GLuint image = GL_NONE; @@ -1722,8 +1722,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) const bool limited_range = !g_cfg.video.full_rgb_range_output; gl::screen.bind(); - glViewport(0, 0, m_frame->client_width(), m_frame->client_height()); - m_video_output_pass.run(m_frame->client_width(), m_frame->client_height(), image, areai(aspect_ratio), gamma, limited_range); + m_video_output_pass.run(areau(aspect_ratio), image, gamma, limited_range); } } @@ -1749,14 +1748,13 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) if (m_overlay_manager->has_visible()) { gl::screen.bind(); - glViewport(0, 0, m_frame->client_width(), m_frame->client_height()); // Lock to avoid modification during run-update chain std::lock_guard lock(*m_overlay_manager); for (const auto& view : m_overlay_manager->get_views()) { - m_ui_renderer.run(m_frame->client_width(), m_frame->client_height(), 0, *view.get()); + m_ui_renderer.run(areau(aspect_ratio), 0, *view.get()); } } } diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 4c2207b3b7..92126defe3 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -132,7 +132,7 @@ namespace gl glBindVertexArray(old_vao); } - virtual void run(u16 w, u16 h, GLuint target_texture, bool depth_target, bool use_blending = false) + virtual void run(const areau& region, GLuint target_texture, bool depth_target, bool use_blending = false) { if (!compiled) { @@ -198,7 +198,7 @@ namespace gl } // Set initial state - glViewport(0, 0, w, h); + 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); @@ -311,7 +311,7 @@ namespace gl saved_sampler_state saved(31, m_sampler); glBindTexture(GL_TEXTURE_2D, source->id()); - overlay_pass::run(dst_area.x2, dst_area.y2, target->id(), true); + overlay_pass::run(dst_area, target->id(), true); } }; @@ -341,12 +341,12 @@ namespace gl "}\n"; } - void run(u16 w, u16 h, GLuint target, GLuint source) + void run(const areau& viewport, GLuint target, GLuint source) { saved_sampler_state saved(31, m_sampler); glBindTexture(GL_TEXTURE_2D, source); - overlay_pass::run(w, h, target, false); + overlay_pass::run(viewport, target, false); } }; @@ -608,9 +608,9 @@ namespace gl } } - void run(u16 w, u16 h, GLuint target, rsx::overlays::overlay& ui) + void run(const areau& viewport, GLuint target, rsx::overlays::overlay& ui) { - program_handle.uniforms["viewport"] = color2f(f32(w), f32(h)); + program_handle.uniforms["viewport"] = color2f((f32)viewport.width(), (f32)viewport.height()); program_handle.uniforms["ui_scale"] = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f); program_handle.uniforms["time"] = (f32)(get_system_time() / 1000) * 0.005f; @@ -658,7 +658,7 @@ namespace gl program_handle.uniforms["blur_strength"] = (s32)cmd.config.blur_strength; program_handle.uniforms["clip_region"] = (s32)cmd.config.clip_region; program_handle.uniforms["clip_bounds"] = cmd.config.clip_rect; - overlay_pass::run(w, h, target, false, true); + overlay_pass::run(viewport, target, false, true); } ui.update(); @@ -672,17 +672,13 @@ namespace gl vs_src = "#version 420\n\n" "layout(location=0) out vec2 tc0;\n" - "uniform float x_scale;\n" - "uniform float y_scale;\n" - "uniform float x_offset;\n" - "uniform float y_offset;\n" "\n" "void main()\n" "{\n" " vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n" " vec2 coords[] = {vec2(0., 1.), vec2(1., 1.), vec2(0., 0.), vec2(1., 0.)};\n" " tc0 = coords[gl_VertexID % 4];\n" - " vec2 pos = positions[gl_VertexID % 4] * vec2(x_scale, y_scale) + (2. * vec2(x_offset, y_offset));\n" + " vec2 pos = positions[gl_VertexID % 4];\n" " gl_Position = vec4(pos, 0., 1.);\n" "}\n"; @@ -708,23 +704,14 @@ namespace gl input_filter = GL_LINEAR; } - void run(u16 w, u16 h, GLuint source, const areai& region, f32 gamma, bool limited_rgb) + void run(const areau& viewport, GLuint source, f32 gamma, bool limited_rgb) { - const f32 x_scale = (f32)(region.x2 - region.x1) / w; - const f32 y_scale = (f32)(region.y2 - region.y1) / h; - const f32 x_offset = (f32)(region.x1) / w; - const f32 y_offset = (f32)(region.y1) / h; - - program_handle.uniforms["x_scale"] = x_scale; - program_handle.uniforms["y_scale"] = y_scale; - program_handle.uniforms["x_offset"] = x_offset; - program_handle.uniforms["y_offset"] = y_offset; program_handle.uniforms["gamma"] = gamma; program_handle.uniforms["limit_range"] = (int)limited_rgb; saved_sampler_state saved(31, m_sampler); glBindTexture(GL_TEXTURE_2D, source); - overlay_pass::run(w, h, GL_NONE, false, false); + overlay_pass::run(viewport, GL_NONE, false, false); } }; } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index e3ccc2e041..6e98b150af 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2023,8 +2023,7 @@ void VKGSRender::clear_surface(u32 mask) renderpass = vk::get_renderpass(*m_device, key); } - m_attachment_clear_pass->run(*m_current_command_buffer, rtt, - region.rect, renderpass); + m_attachment_clear_pass->run(*m_current_command_buffer, rtt, region.rect, renderpass); rtt->change_layout(*m_current_command_buffer, old_layout); } @@ -3425,7 +3424,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) for (const auto& view : m_overlay_manager->get_views()) { - m_ui_renderer->run(*m_current_command_buffer, direct_fbo->width(), direct_fbo->height(), direct_fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get()); + m_ui_renderer->run(*m_current_command_buffer, areau(aspect_ratio), direct_fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get()); } } diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index eb69517130..eb321ba64a 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -327,51 +327,53 @@ namespace vk vkCmdDraw(cmd, num_drawable_elements, 1, first_vertex, 0); } - virtual void set_up_viewport(vk::command_buffer &cmd, u16 max_w, u16 max_h) + virtual void set_up_viewport(vk::command_buffer &cmd, u32 x, u32 y, u32 w, u32 h) { VkViewport vp{}; - vp.width = (f32)max_w; - vp.height = (f32)max_h; + vp.x = (f32)x; + vp.y = (f32)y; + vp.width = (f32)w; + vp.height = (f32)h; vp.minDepth = 0.f; vp.maxDepth = 1.f; vkCmdSetViewport(cmd, 0, 1, &vp); - VkRect2D vs = { { 0, 0 }, { 0u + max_w, 0u + max_h } }; + VkRect2D vs = { { (s32)x, (s32)y }, { w, h } }; vkCmdSetScissor(cmd, 0, 1, &vs); } - void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* fbo, const std::vector& src, VkRenderPass render_pass) + void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* fbo, const std::vector& src, VkRenderPass render_pass) { load_program(cmd, render_pass, src); - set_up_viewport(cmd, w, h); + set_up_viewport(cmd, viewport.x1, viewport.y1, viewport.width(), viewport.height()); VkRenderPassBeginInfo rp_begin = {}; rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rp_begin.renderPass = render_pass; rp_begin.framebuffer = fbo->value; - rp_begin.renderArea.offset.x = 0; - rp_begin.renderArea.offset.y = 0; - rp_begin.renderArea.extent.width = w; - rp_begin.renderArea.extent.height = h; + rp_begin.renderArea.offset.x = (s32)viewport.x1; + rp_begin.renderArea.offset.y = (s32)viewport.y1; + rp_begin.renderArea.extent.width = viewport.width(); + rp_begin.renderArea.extent.height = viewport.height(); vkCmdBeginRenderPass(cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); emit_geometry(cmd); vkCmdEndRenderPass(cmd); } - void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, const std::vector& src, VkRenderPass render_pass) + void run(vk::command_buffer &cmd, const areau& viewport, vk::image* target, const std::vector& src, VkRenderPass render_pass) { auto fbo = static_cast(get_framebuffer(target, render_pass)); fbo->add_ref(); - run(cmd, w, h, fbo, src, render_pass); + run(cmd, viewport, fbo, src, render_pass); fbo->release(); } - void run(vk::command_buffer &cmd, u16 w, u16 h, vk::image* target, vk::image_view* src, VkRenderPass render_pass) + void run(vk::command_buffer &cmd, const areau& viewport, vk::image* target, vk::image_view* src, VkRenderPass render_pass) { std::vector views = { src }; - run(cmd, w, h, target, views, render_pass); + run(cmd, viewport, target, views, render_pass); } }; @@ -433,7 +435,7 @@ namespace vk src_scale_x = f32(src_area.x2) / real_src->width(); src_scale_y = f32(src_area.y2) / real_src->height(); - overlay_pass::run(cmd, dst_area.x2, dst_area.y2, dst, src, render_pass); + overlay_pass::run(cmd, dst_area, dst, src, render_pass); } }; @@ -756,12 +758,12 @@ namespace vk } } - void run(vk::command_buffer &cmd, u16 w, u16 h, vk::framebuffer* target, VkRenderPass render_pass, + void run(vk::command_buffer &cmd, const areau& viewport, vk::framebuffer* target, VkRenderPass render_pass, vk::data_heap &upload_heap, rsx::overlays::overlay &ui) { m_scale_offset = color4f((f32)ui.virtual_width, (f32)ui.virtual_height, 1.f, 1.f); m_time = (f32)(get_system_time() / 1000) * 0.005f; - m_viewport_size = { f32(w), f32(h) }; + m_viewport_size = { f32(viewport.width()), f32(viewport.height()) }; for (auto &command : ui.get_compiled().draw_commands) { @@ -799,7 +801,7 @@ namespace vk break; } - overlay_pass::run(cmd, w, h, target, { src }, render_pass); + overlay_pass::run(cmd, viewport, target, { src }, render_pass); } ui.update(); @@ -877,11 +879,13 @@ namespace vk vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data); } - void set_up_viewport(vk::command_buffer &cmd, u16 max_w, u16 max_h) override + void set_up_viewport(vk::command_buffer &cmd, u32 x, u32 y, u32 w, u32 h) override { VkViewport vp{}; - vp.width = (f32)max_w; - vp.height = (f32)max_h; + vp.x = (f32)x; + vp.y = (f32)y; + vp.width = (f32)w; + vp.height = (f32)h; vp.minDepth = 0.f; vp.maxDepth = 1.f; vkCmdSetViewport(cmd, 0, 1, &vp); @@ -915,9 +919,8 @@ namespace vk // Coverage sampling disabled, but actually report correct number of samples renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false); - overlay_pass::run(cmd, target->width(), target->height(), target, - target->get_view(0xAAE4, rsx::default_remap_vector), - render_pass); + overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target, + target->get_view(0xAAE4, rsx::default_remap_vector), render_pass); } }; } diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.h b/rpcs3/Emu/RSX/VK/VKResolveHelper.h index a12d0fee0e..791fd55ed8 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.h +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.h @@ -268,7 +268,7 @@ namespace vk overlay_pass::run( cmd, - (u16)resolve_image->width(), (u16)resolve_image->height(), + { 0, 0, resolve_image->width(), resolve_image->height() }, resolve_image, src_view, render_pass); } @@ -299,7 +299,7 @@ namespace vk overlay_pass::run( cmd, - (u16)msaa_image->width(), (u16)msaa_image->height(), + { 0, 0, msaa_image->width(), msaa_image->height() }, msaa_image, src_view, render_pass); } @@ -364,7 +364,7 @@ namespace vk overlay_pass::run( cmd, - (u16)resolve_image->width(), (u16)resolve_image->height(), + { 0, 0, resolve_image->width(), resolve_image->height() }, resolve_image, stencil_view, render_pass); } @@ -432,7 +432,7 @@ namespace vk overlay_pass::run( cmd, - (u16)msaa_image->width(), (u16)msaa_image->height(), + { 0, 0, msaa_image->width(), msaa_image->height() }, msaa_image, stencil_view, render_pass); } @@ -474,7 +474,7 @@ namespace vk overlay_pass::run( cmd, - (u16)resolve_image->width(), (u16)resolve_image->height(), + { 0, 0, resolve_image->width(), resolve_image->height() }, resolve_image, { depth_view, stencil_view }, render_pass); } @@ -519,7 +519,7 @@ namespace vk overlay_pass::run( cmd, - (u16)msaa_image->width(), (u16)msaa_image->height(), + { 0, 0, msaa_image->width(), msaa_image->height() }, msaa_image, { depth_view, stencil_view }, render_pass); }