hwr2: add g_wipeskiprender 1-frame workaround

This commit is contained in:
Eidolon 2023-02-20 21:27:21 -06:00
parent 158aaa6803
commit 1958394635
8 changed files with 58 additions and 55 deletions

View file

@ -690,6 +690,9 @@ static void D_Display(void)
ps_swaptime = I_GetPreciseTime();
I_FinishUpdate(); // page flip or blit buffer
ps_swaptime = I_GetPreciseTime() - ps_swaptime;
// We should never do the HWR2 skip 3d drawing hack for more than 1 full draw.
g_wipeskiprender = false;
}
}

View file

@ -340,8 +340,8 @@ void F_WipeStartScreen(void)
return;
}
#endif
// wipe_scr_start = screens[3];
// I_ReadScreen(wipe_scr_start);
wipe_scr_start = screens[3];
I_ReadScreen(wipe_scr_start);
I_FinishUpdateWipeStartScreen();
#endif
}
@ -358,9 +358,9 @@ void F_WipeEndScreen(void)
return;
}
#endif
// wipe_scr_end = screens[4];
// I_ReadScreen(wipe_scr_end);
// V_DrawBlock(0, 0, 0, vid.width, vid.height, wipe_scr_start);
wipe_scr_end = screens[4];
I_ReadScreen(wipe_scr_end);
V_DrawBlock(0, 0, 0, vid.width, vid.height, wipe_scr_start);
I_FinishUpdateWipeEndScreen();
#endif
}

View file

@ -30,7 +30,7 @@ class BlitRectPass final : public Pass
uint32_t output_width_ = 0;
uint32_t output_height_ = 0;
bool output_correct_aspect_ = false;
bool output_clear_ = true;
bool output_clear_ = false;
bool output_flip_ = false;
rhi::Handle<rhi::RenderPass> render_pass_;
rhi::Handle<rhi::Buffer> quad_vbo_;
@ -84,6 +84,8 @@ public:
output_correct_aspect_ = correct_aspect;
output_flip_ = flip;
}
void clear_output(bool clear) noexcept { output_clear_ = clear; }
};
} // namespace srb2::hwr2

View file

@ -33,15 +33,10 @@ void FramebufferManager::prepass(Rhi& rhi)
// Destroy the framebuffer textures if they exist and the video size changed
if (width_ != current_width || height_ != current_height)
{
if (main_colors_[0] != kNullHandle)
if (main_color_ != kNullHandle)
{
rhi.destroy_texture(main_colors_[0]);
main_colors_[0] = kNullHandle;
}
if (main_colors_[1] != kNullHandle)
{
rhi.destroy_texture(main_colors_[1]);
main_colors_[1] = kNullHandle;
rhi.destroy_texture(main_color_);
main_color_ = kNullHandle;
}
if (main_depth_ != kNullHandle)
{
@ -74,13 +69,9 @@ void FramebufferManager::prepass(Rhi& rhi)
height_ = current_height;
// Recreate the framebuffer textures
if (main_colors_[0] == kNullHandle)
if (main_color_ == kNullHandle)
{
main_colors_[0] = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
}
if (main_colors_[1] == kNullHandle)
{
main_colors_[1] = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
main_color_ = rhi.create_texture({TextureFormat::kRGBA, current_width, current_height});
}
if (main_depth_ == kNullHandle)
{

View file

@ -22,12 +22,11 @@ namespace srb2::hwr2
class FramebufferManager final : public Pass
{
std::array<rhi::Handle<rhi::Texture>, 2> main_colors_;
rhi::Handle<rhi::Texture> main_color_;
rhi::Handle<rhi::Renderbuffer> main_depth_;
std::array<rhi::Handle<rhi::Texture>, 2> post_colors_;
rhi::Handle<rhi::Texture> wipe_start_color_;
rhi::Handle<rhi::Texture> wipe_end_color_;
std::size_t main_index_ = 0;
std::size_t post_index_ = 0;
std::size_t width_ = 0;
std::size_t height_ = 0;
@ -42,9 +41,6 @@ public:
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
virtual void postpass(rhi::Rhi& rhi) override;
/// @brief Swap the current and previous main colors.
void swap_main() noexcept { main_index_ = main_index_ == 0 ? 1 : 0; }
/// @brief Swap the current and previous postprocess FB textures. Use between pass prepass phases to alternate.
void swap_post() noexcept
{
@ -54,9 +50,8 @@ public:
void reset_post() noexcept { first_postprocess_ = true; }
rhi::Handle<rhi::Texture> current_main_color() const noexcept { return main_colors_[main_index_]; }
rhi::Handle<rhi::Texture> main_color() const noexcept { return main_color_; }
rhi::Handle<rhi::Renderbuffer> main_depth() const noexcept { return main_depth_; }
rhi::Handle<rhi::Texture> previous_main_color() const noexcept { return main_colors_[1 - main_index_]; }
rhi::Handle<rhi::Texture> current_post_color() const noexcept { return post_colors_[post_index_]; }
@ -64,7 +59,7 @@ public:
{
if (first_postprocess_)
{
return current_main_color();
return main_color();
}
return post_colors_[1 - post_index_];
};

View file

@ -150,11 +150,11 @@ static InternalPassData build_pass_manager()
"3d_prepare",
[framebuffer_manager](PassManager& mgr, Rhi&)
{
const bool sw_enabled = rendermode == render_soft;
const bool sw_enabled = rendermode == render_soft && gamestate != GS_NULL;
mgr.set_pass_enabled("software", sw_enabled);
mgr.set_pass_enabled("blit_sw_prepare", sw_enabled);
mgr.set_pass_enabled("blit_sw", sw_enabled);
mgr.set_pass_enabled("blit_sw", sw_enabled && !g_wipeskiprender);
}
);
basic_rendering->insert("software", software_pass);
@ -163,7 +163,7 @@ static InternalPassData build_pass_manager()
[blit_sw_pass, software_pass, framebuffer_manager](PassManager&, Rhi&)
{
blit_sw_pass->set_texture(software_pass->screen_texture(), vid.width, vid.height);
blit_sw_pass->set_output(framebuffer_manager->current_main_color(), vid.width, vid.height, false, false);
blit_sw_pass->set_output(framebuffer_manager->main_color(), vid.width, vid.height, false, false);
}
);
basic_rendering->insert("blit_sw", blit_sw_pass);
@ -172,7 +172,7 @@ static InternalPassData build_pass_manager()
"2d_prepare",
[twodee, framebuffer_manager, palette_manager](PassManager& mgr, Rhi&)
{
twodee->output_ = framebuffer_manager->current_main_color();
twodee->output_ = framebuffer_manager->main_color();
twodee->palette_manager_ = palette_manager;
twodee->output_width_ = vid.width;
twodee->output_height_ = vid.height;
@ -180,35 +180,17 @@ static InternalPassData build_pass_manager()
);
basic_rendering->insert("2d", twodee);
// basic_rendering->insert(
// "pp_final_prepare",
// [](PassManager& mgr, Rhi&)
// {
// mgr.set_pass_enabled("pp_final_wipe_prepare", WipeInAction);
// mgr.set_pass_enabled("pp_final_wipe", WipeInAction);
// mgr.set_pass_enabled("pp_final_wipe_flip", WipeInAction);
// }
// );
basic_rendering->insert(
"pp_final_simple_blit_prepare",
[pp_simple_blit_pass, framebuffer_manager](PassManager&, Rhi&)
{
framebuffer_manager->swap_post();
pp_simple_blit_pass->set_texture(framebuffer_manager->current_main_color(), vid.width, vid.height);
pp_simple_blit_pass->set_texture(framebuffer_manager->main_color(), vid.width, vid.height);
pp_simple_blit_pass
->set_output(framebuffer_manager->current_post_color(), vid.width, vid.height, false, true);
}
);
basic_rendering->insert("pp_final_simple_blit", pp_simple_blit_pass);
// basic_rendering->insert(
// "pp_final_simple_blit_flip",
// [framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
// );
// basic_rendering->insert(
// "pp_final_wipe_flip",
// [framebuffer_manager](PassManager&, Rhi&) { framebuffer_manager->swap_post(); }
// );
basic_rendering->insert(
"screenshot_prepare",
@ -270,18 +252,33 @@ static InternalPassData build_pass_manager()
// Wipe End Screen Capture rendering
auto wipe_capture_end_rendering = std::make_shared<PassManager>();
auto wipe_end_blit = std::make_shared<BlitRectPass>();
auto wipe_end_blit_start_to_main = std::make_shared<BlitRectPass>();
wipe_capture_end_rendering->insert("resource_manager", resource_manager);
wipe_capture_end_rendering->insert("basic_rendering", basic_rendering);
wipe_capture_end_rendering->insert(
"wipe_capture_prepare",
[framebuffer_manager, wipe_end_blit](PassManager&, Rhi&)
[framebuffer_manager, wipe_end_blit, wipe_end_blit_start_to_main](PassManager&, Rhi&)
{
wipe_end_blit->set_texture(framebuffer_manager->current_post_color(), vid.width, vid.height);
wipe_end_blit->set_output(framebuffer_manager->wipe_end_color(), vid.width, vid.height, false, true);
wipe_end_blit_start_to_main->set_texture(
framebuffer_manager->wipe_start_color(),
vid.width,
vid.height
);
wipe_end_blit_start_to_main->set_output(
framebuffer_manager->main_color(),
vid.width,
vid.height,
false,
true
);
}
);
wipe_capture_end_rendering->insert("wipe_capture", wipe_end_blit);
wipe_capture_end_rendering->insert("wipe_end_blit_start_to_main", wipe_end_blit_start_to_main);
// Wipe rendering only runs the wipe shader on the start and end screens, and adds composite-present.
auto wipe_rendering = std::make_shared<PassManager>();
@ -294,7 +291,7 @@ static InternalPassData build_pass_manager()
[pp_wipe_pass, framebuffer_manager, common_resources_manager](PassManager&, Rhi&)
{
framebuffer_manager->swap_post();
Handle<Texture> start = framebuffer_manager->wipe_start_color();
Handle<Texture> start = framebuffer_manager->main_color();
Handle<Texture> end = framebuffer_manager->wipe_end_color();
if (g_wipereverse)
{

View file

@ -334,7 +334,7 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
{
sprintf(mapname, "ID %d", gamemap-1);
}
CON_LogMessage("Map ");
CON_LogMessage(mapname);
CON_LogMessage(" is corrupt: ");
@ -7499,9 +7499,14 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// This is needed. Don't touch.
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
// HWR2 skip 3d render draw hack to avoid losing the current wipe screen
g_wipeskiprender = true;
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
g_wipeskiprender = false;
// Reset the palette
if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL");

View file

@ -336,9 +336,14 @@ void Y_IntermissionDrawer(void)
{
INT32 i, whiteplayer = MAXPLAYERS, x = 4, hilicol = highlightflags;
// If we early return, skip drawing the 3D scene (software buffer) so it doesn't clobber the frame for the wipe
g_wipeskiprender = true;
if (intertype == int_none || rendermode == render_none)
return;
g_wipeskiprender = false;
// the merge was kind of a mess, how does this work -- toast 171021
{
M_DrawMenuBackground();
@ -810,7 +815,7 @@ void Y_StartIntermission(void)
if (!timer)
{
// Prevent a weird bug
timer = 1;
timer = 1;
}
else if (nump < 2 && !netgame)
{
@ -945,6 +950,9 @@ void Y_VoteDrawer(void)
UINT8 selected[4];
fixed_t rubyheight = 0;
// If we early return, skip drawing the 3D scene (software buffer) so it doesn't clobber the frame for the wipe
g_wipeskiprender = true;
if (rendermode == render_none)
return;
@ -954,6 +962,8 @@ void Y_VoteDrawer(void)
if (!voteclient.loaded)
return;
g_wipeskiprender = false;
{
static angle_t rubyfloattime = 0;
rubyheight = FINESINE(rubyfloattime>>ANGLETOFINESHIFT);