From 18efb35602e2e9e6348b26dc6f722000ce31d0a9 Mon Sep 17 00:00:00 2001 From: "James R." Date: Sat, 30 Sep 2023 16:07:53 -0700 Subject: [PATCH 1/5] SDLSetMode: render immediately after resolution change to avoid 1-frame of texture presented at wrong size --- src/sdl/i_video.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 84af0eed8..bd47a09c6 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -235,6 +235,11 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool SDL_GetWindowSize(window, &width, &height); vid.realwidth = static_cast(width); vid.realheight = static_cast(height); + + if (graphics_started) + { + I_UpdateNoVsync(); + } } static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) From 2d9d06e2671fdbc8b98545f3a0c30ff2d7db14cf Mon Sep 17 00:00:00 2001 From: "James R." Date: Sat, 30 Sep 2023 16:09:10 -0700 Subject: [PATCH 2/5] Let window be resizable --- src/sdl/i_video.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index bd47a09c6..329b52476 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -506,6 +506,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) case SDL_WINDOWEVENT_MOVED: window_x = evt.data1; window_y = evt.data2; + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + vid.realwidth = evt.data1; + vid.realheight = evt.data2; + break; } if (FOCUSUNION == oldfocus) // No state change @@ -1540,7 +1545,7 @@ INT32 VID_SetMode(INT32 modeNum) static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) { - int flags = 0; + uint32_t flags = SDL_WINDOW_RESIZABLE; if (rendermode == render_none) // dedicated return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh From 37dc1189bb660f262722feadb5292db6941fde5b Mon Sep 17 00:00:00 2001 From: "James R." Date: Sat, 30 Sep 2023 16:38:56 -0700 Subject: [PATCH 3/5] srb2::hwr2::BlitRectPass::set_output: set x/y as well --- src/f_wipe.cpp | 2 +- src/hwr2/blit_rect.cpp | 4 ++-- src/hwr2/blit_rect.hpp | 8 ++++---- src/i_video_common.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index 39a7b2aa4..6a8587586 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -432,7 +432,7 @@ void F_WipeEndScreen(void) dst_region.h = std::min(dst_region.h, backbuf_deets.height); rhi->copy_framebuffer_to_texture(ctx, hw_state->wipe_frames.end, dst_region, dst_region); - hw_state->blit_rect->set_output(dst_region.w, dst_region.h, false, true); + hw_state->blit_rect->set_output(0, 0, dst_region.w, dst_region.h, false, true); rhi::TextureDetails start_deets = rhi->get_texture_details(hw_state->wipe_frames.start); hw_state->blit_rect->set_texture(hw_state->wipe_frames.start, start_deets.width, start_deets.height); hw_state->blit_rect->draw(*rhi, ctx); diff --git a/src/hwr2/blit_rect.cpp b/src/hwr2/blit_rect.cpp index a5101e0f0..df3e791bb 100644 --- a/src/hwr2/blit_rect.cpp +++ b/src/hwr2/blit_rect.cpp @@ -100,7 +100,7 @@ void BlitRectPass::transfer(Rhi& rhi, Handle ctx) if (output_correct_aspect_) { aspect = static_cast(texture_width_) / static_cast(texture_height_); - output_aspect = static_cast(output_width_) / static_cast(output_height_); + output_aspect = static_cast(output_position_.w) / static_cast(output_position_.h); } bool taller = aspect > output_aspect; @@ -137,7 +137,7 @@ void BlitRectPass::transfer(Rhi& rhi, Handle ctx) void BlitRectPass::graphics(Rhi& rhi, Handle ctx) { rhi.bind_pipeline(ctx, pipeline_); - rhi.set_viewport(ctx, {0, 0, output_width_, output_height_}); + rhi.set_viewport(ctx, output_position_); rhi.bind_uniform_set(ctx, 0, uniform_sets_[0]); rhi.bind_uniform_set(ctx, 1, uniform_sets_[1]); rhi.bind_binding_set(ctx, binding_set_); diff --git a/src/hwr2/blit_rect.hpp b/src/hwr2/blit_rect.hpp index 014a876bb..f2acd9887 100644 --- a/src/hwr2/blit_rect.hpp +++ b/src/hwr2/blit_rect.hpp @@ -26,8 +26,7 @@ class BlitRectPass uint32_t texture_width_ = 0; uint32_t texture_height_ = 0; rhi::Handle output_; - uint32_t output_width_ = 0; - uint32_t output_height_ = 0; + rhi::Rect output_position_; bool output_correct_aspect_ = false; bool output_flip_ = false; rhi::Handle quad_vbo_; @@ -63,14 +62,15 @@ public: /// @param width texture width /// @param height texture height void set_output( + int32_t x, + int32_t y, uint32_t width, uint32_t height, bool correct_aspect, bool flip ) noexcept { - output_width_ = width; - output_height_ = height; + output_position_ = {x, y, width, height}; output_correct_aspect_ = correct_aspect; output_flip_ = flip; } diff --git a/src/i_video_common.cpp b/src/i_video_common.cpp index 78eecf3fe..b25eee29e 100644 --- a/src/i_video_common.cpp +++ b/src/i_video_common.cpp @@ -329,7 +329,7 @@ void I_FinishUpdate(void) rhi->begin_default_render_pass(ctx, true); // Upscale draw the backbuffer (with postprocessing maybe?) - g_hw_state.blit_rect->set_output(vid.realwidth, vid.realheight, true, true); + g_hw_state.blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true); g_hw_state.blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast(vid.width), static_cast(vid.height)); g_hw_state.blit_rect->draw(*rhi, ctx); rhi->end_render_pass(ctx); From 2ec5d3e6b03240eaf75b7667cbf57148d5639567 Mon Sep 17 00:00:00 2001 From: "James R." Date: Sat, 30 Sep 2023 16:50:41 -0700 Subject: [PATCH 4/5] Add scr_scale, scr_x, scr_y cvars to scale and adjust viewport position --- src/cvars.cpp | 4 ++++ src/i_video_common.cpp | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cvars.cpp b/src/cvars.cpp index 2dad5faef..5e56394ef 100644 --- a/src/cvars.cpp +++ b/src/cvars.cpp @@ -421,6 +421,10 @@ consvar_t cv_scr_depth = Player("scr_depth", "16 bits").values({{8, "8 bits"}, { consvar_t cv_scr_width = Player("scr_width", "640").values(CV_Unsigned); consvar_t cv_scr_height = Player("scr_height", "400").values(CV_Unsigned); +consvar_t cv_scr_scale = Player("scr_scale", "1.0").floating_point(); +consvar_t cv_scr_x = Player("scr_x", "0.0").floating_point(); +consvar_t cv_scr_y = Player("scr_y", "0.0").floating_point(); + consvar_t cv_seenames = Player("seenames", "On").on_off(); consvar_t cv_shadow = Player("shadow", "On").on_off(); consvar_t cv_shittyscreen = Player("televisionsignal", "Okay").flags(CV_NOSHOWHELP).values({{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}}).dont_save(); diff --git a/src/i_video_common.cpp b/src/i_video_common.cpp index b25eee29e..29d7eb37f 100644 --- a/src/i_video_common.cpp +++ b/src/i_video_common.cpp @@ -16,8 +16,10 @@ #include #include +#include "command.h" #include "cxxutil.hpp" #include "f_finale.h" +#include "m_fixed.h" #include "m_misc.h" #include "hwr2/hardware_state.hpp" #include "hwr2/patch_atlas.hpp" @@ -46,6 +48,8 @@ #include "st_stuff.h" #include "v_video.h" +extern "C" consvar_t cv_scr_scale, cv_scr_x, cv_scr_y; + using namespace srb2; using namespace srb2::hwr2; using namespace srb2::rhi; @@ -329,7 +333,20 @@ void I_FinishUpdate(void) rhi->begin_default_render_pass(ctx, true); // Upscale draw the backbuffer (with postprocessing maybe?) - g_hw_state.blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true); + if (cv_scr_scale.value != FRACUNIT) + { + float f = std::max(FixedToFloat(cv_scr_scale.value), 0.f); + float w = vid.realwidth * f; + float h = vid.realheight * f; + float x = (vid.realwidth - w) * (0.5f + (FixedToFloat(cv_scr_x.value) * 0.5f)); + float y = (vid.realheight - h) * (0.5f + (FixedToFloat(cv_scr_y.value) * 0.5f)); + + g_hw_state.blit_rect->set_output(x, y, w, h, true, true); + } + else + { + g_hw_state.blit_rect->set_output(0, 0, vid.realwidth, vid.realheight, true, true); + } g_hw_state.blit_rect->set_texture(g_hw_state.backbuffer->color(), static_cast(vid.width), static_cast(vid.height)); g_hw_state.blit_rect->draw(*rhi, ctx); rhi->end_render_pass(ctx); From a7382ca9d00e0a29cda15b222d2abdd7974e2bcd Mon Sep 17 00:00:00 2001 From: "James R." Date: Sat, 30 Sep 2023 19:21:53 -0700 Subject: [PATCH 5/5] UpscaleBackbuffer::begin_pass: use separate renderpass to clear framebuffer if texture was recreated Fixes wipes potentially reading invalid data from the framebuffer if the texture was recreated but not yet rendered to. --- src/hwr2/upscale_backbuffer.cpp | 36 ++++++++++++++++++++++----------- src/hwr2/upscale_backbuffer.hpp | 1 + 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/hwr2/upscale_backbuffer.cpp b/src/hwr2/upscale_backbuffer.cpp index 0d3666e5c..f7e187388 100644 --- a/src/hwr2/upscale_backbuffer.cpp +++ b/src/hwr2/upscale_backbuffer.cpp @@ -37,6 +37,19 @@ void UpscaleBackbuffer::begin_pass(Rhi& rhi, Handle ctx) remake = true; } + auto new_renderpass = [&rhi = rhi](AttachmentLoadOp load_op, AttachmentStoreOp store_op) + { + RenderPassDesc desc {}; + desc.use_depth_stencil = true; + desc.color_load_op = load_op; + desc.color_store_op = store_op; + desc.depth_load_op = load_op; + desc.depth_store_op = store_op; + desc.stencil_load_op = load_op; + desc.stencil_store_op = store_op; + return rhi.create_render_pass(desc); + }; + if (remake) { if (color_) @@ -63,23 +76,22 @@ void UpscaleBackbuffer::begin_pass(Rhi& rhi, Handle ctx) depth_tex.height = vid_height; depth_ = rhi.create_renderbuffer(depth_tex); - } - if (!renderpass_) + if (!renderpass_clear_) + { + renderpass_clear_ = new_renderpass(AttachmentLoadOp::kClear, AttachmentStoreOp::kStore); + } + } + else { - RenderPassDesc desc {}; - desc.use_depth_stencil = true; - desc.color_load_op = AttachmentLoadOp::kLoad; - desc.color_store_op = AttachmentStoreOp::kStore; - desc.depth_load_op = AttachmentLoadOp::kLoad; - desc.depth_store_op = AttachmentStoreOp::kStore; - desc.stencil_load_op = AttachmentLoadOp::kLoad; - desc.stencil_store_op = AttachmentStoreOp::kStore; - renderpass_ = rhi.create_render_pass(desc); + if (!renderpass_) + { + renderpass_ = new_renderpass(AttachmentLoadOp::kLoad, AttachmentStoreOp::kStore); + } } RenderPassBeginInfo begin_info {}; - begin_info.render_pass = renderpass_; + begin_info.render_pass = remake ? renderpass_clear_ : renderpass_; begin_info.clear_color = {0, 0, 0, 1}; begin_info.color_attachment = color_; begin_info.depth_stencil_attachment = depth_; diff --git a/src/hwr2/upscale_backbuffer.hpp b/src/hwr2/upscale_backbuffer.hpp index d7b34a276..0f6903dd1 100644 --- a/src/hwr2/upscale_backbuffer.hpp +++ b/src/hwr2/upscale_backbuffer.hpp @@ -20,6 +20,7 @@ class UpscaleBackbuffer rhi::Handle color_; rhi::Handle depth_; rhi::Handle renderpass_; + rhi::Handle renderpass_clear_; public: UpscaleBackbuffer();