hwr2: upscale chosen resolution to desktop res

This commit is contained in:
Eidolon 2023-08-31 20:11:48 -05:00
parent 6f580606cd
commit 78ccaf361b
8 changed files with 155 additions and 13 deletions

View file

@ -226,8 +226,6 @@ INT32 lastwipetic = 0;
#define GENLEN 31
static UINT8 *wipe_scr_start; //screen 3
static UINT8 *wipe_scr_end; //screen 4
static UINT8 *wipe_scr; //screen 0 (main drawing)
static UINT8 pallen;
static fixed_t paldiv;
@ -385,8 +383,11 @@ void F_WipeStartScreen(void)
hw_state->twodee_renderer->flush(*rhi, ctx, g_2d);
rhi::Rect copy_region = {0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)};
rhi->copy_framebuffer_to_texture(ctx, hw_state->wipe_frames.start, copy_region, copy_region);
rhi::Rect dst_region = {0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)};
rhi::TextureDetails backbuf_deets = rhi->get_texture_details(hw_state->backbuffer->color());
dst_region.w = std::min(dst_region.w, backbuf_deets.width);
dst_region.h = std::min(dst_region.h, backbuf_deets.height);
rhi->copy_framebuffer_to_texture(ctx, hw_state->wipe_frames.start, dst_region, dst_region);
I_FinishUpdate();
#endif
@ -425,10 +426,13 @@ void F_WipeEndScreen(void)
hw_state->twodee_renderer->flush(*rhi, ctx, g_2d);
rhi::Rect copy_region = {0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)};
rhi->copy_framebuffer_to_texture(ctx, hw_state->wipe_frames.end, copy_region, copy_region);
rhi::Rect dst_region = {0, 0, static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height)};
rhi::TextureDetails backbuf_deets = rhi->get_texture_details(hw_state->backbuffer->color());
dst_region.w = std::min(dst_region.w, backbuf_deets.width);
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(copy_region.w, copy_region.h, false, true);
hw_state->blit_rect->set_output(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);

View file

@ -27,4 +27,6 @@ target_sources(SRB2SDL2 PRIVATE
twodee.hpp
twodee_renderer.cpp
twodee_renderer.hpp
upscale_backbuffer.cpp
upscale_backbuffer.hpp
)

View file

@ -17,6 +17,7 @@
#include "screen_capture.hpp"
#include "software_screen_renderer.hpp"
#include "twodee_renderer.hpp"
#include "upscale_backbuffer.hpp"
namespace srb2::hwr2
{
@ -38,6 +39,7 @@ struct HardwareState
std::unique_ptr<PostprocessWipePass> wipe;
std::unique_ptr<BlitRectPass> blit_rect;
std::unique_ptr<ScreenshotPass> screen_capture;
std::unique_ptr<UpscaleBackbuffer> backbuffer;
WipeFrames wipe_frames;
};

View file

@ -0,0 +1,87 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#include "upscale_backbuffer.hpp"
#include "../i_video.h"
using namespace srb2;
using namespace srb2::rhi;
using namespace srb2::hwr2;
UpscaleBackbuffer::UpscaleBackbuffer() = default;
UpscaleBackbuffer::UpscaleBackbuffer(UpscaleBackbuffer&&) = default;
UpscaleBackbuffer::~UpscaleBackbuffer() = default;
UpscaleBackbuffer& UpscaleBackbuffer::operator=(UpscaleBackbuffer&&) = default;
static bool size_equal(Rhi& rhi, Handle<Texture> tex, uint32_t width, uint32_t height)
{
TextureDetails deets = rhi.get_texture_details(tex);
return deets.width == width && deets.height == height;
}
void UpscaleBackbuffer::begin_pass(Rhi& rhi, Handle<GraphicsContext> ctx)
{
uint32_t vid_width = static_cast<uint32_t>(vid.width);
uint32_t vid_height = static_cast<uint32_t>(vid.height);
bool remake = false;
if (!color_ || !size_equal(rhi, color_, vid_width, vid_height))
{
remake = true;
}
if (remake)
{
if (color_)
{
rhi.destroy_texture(color_);
color_ = kNullHandle;
}
if (depth_)
{
rhi.destroy_renderbuffer(depth_);
depth_ = kNullHandle;
}
TextureDesc color_tex {};
color_tex.format = TextureFormat::kRGBA;
color_tex.width = vid_width;
color_tex.height = vid_height;
color_tex.u_wrap = TextureWrapMode::kClamp;
color_tex.v_wrap = TextureWrapMode::kClamp;
color_ = rhi.create_texture(color_tex);
RenderbufferDesc depth_tex {};
depth_tex.width = vid_width;
depth_tex.height = vid_height;
depth_ = rhi.create_renderbuffer(depth_tex);
}
if (!renderpass_)
{
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);
}
RenderPassBeginInfo begin_info {};
begin_info.render_pass = renderpass_;
begin_info.clear_color = {0, 0, 0, 1};
begin_info.color_attachment = color_;
begin_info.depth_stencil_attachment = depth_;
rhi.begin_render_pass(ctx, begin_info);
}

View file

@ -0,0 +1,39 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
#ifndef __SRB2_HWR2_UPSCALE_BACKBUFFER_HPP__
#define __SRB2_HWR2_UPSCALE_BACKBUFFER_HPP__
#include "../rhi/rhi.hpp"
namespace srb2::hwr2
{
class UpscaleBackbuffer
{
rhi::Handle<rhi::Texture> color_;
rhi::Handle<rhi::Renderbuffer> depth_;
rhi::Handle<rhi::RenderPass> renderpass_;
public:
UpscaleBackbuffer();
UpscaleBackbuffer(const UpscaleBackbuffer&) = delete;
UpscaleBackbuffer(UpscaleBackbuffer&&);
~UpscaleBackbuffer();
UpscaleBackbuffer& operator=(const UpscaleBackbuffer&) = delete;
UpscaleBackbuffer& operator=(UpscaleBackbuffer&&);
void begin_pass(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx);
rhi::Handle<rhi::Texture> color() const noexcept { return color_; }
};
} // namespace srb2::hwr2
#endif // __SRB2_HWR2_UPSCALE_BACKBUFFER_HPP__

View file

@ -79,6 +79,7 @@ static void reset_hardware_state(Rhi* rhi)
g_hw_state.wipe = std::make_unique<PostprocessWipePass>();
g_hw_state.blit_rect = std::make_unique<BlitRectPass>();
g_hw_state.screen_capture = std::make_unique<ScreenshotPass>();
g_hw_state.backbuffer = std::make_unique<UpscaleBackbuffer>();
g_hw_state.wipe_frames = {};
g_last_known_rhi = rhi;
@ -278,8 +279,9 @@ void I_StartDisplayUpdate(void)
}
rhi::Handle<rhi::GraphicsContext> ctx = rhi->begin_graphics();
HardwareState* hw_state = &g_hw_state;
rhi->begin_default_render_pass(ctx, false);
hw_state->backbuffer->begin_pass(*rhi, ctx);
g_main_graphics_context = ctx;
@ -318,6 +320,15 @@ void I_FinishUpdate(void)
// better hope the drawing code left the context in a render pass, I guess
g_hw_state.twodee_renderer->flush(*rhi, ctx, g_2d);
rhi->end_render_pass(ctx);
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_texture(g_hw_state.backbuffer->color(), static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));
g_hw_state.blit_rect->draw(*rhi, ctx);
rhi->end_render_pass(ctx);
rhi->end_graphics(ctx);
g_main_graphics_context = kNullHandle;

View file

@ -190,7 +190,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool
if (fullscreen)
{
wasfullscreen = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
else // windowed mode
{
@ -217,7 +217,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool
SDL_SetWindowSize(window, width, height);
if (fullscreen)
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
}

View file

@ -3207,9 +3207,6 @@ void VID_DisplaySoftwareScreen()
// Misnomer; this just uploads the screen to the software indexed screen texture
hw_state->software_screen_renderer->draw(*rhi, ctx);
rhi->end_render_pass(ctx);
rhi->begin_default_render_pass(ctx, false);
const int screens = std::clamp(r_splitscreen + 1, 1, MAXSPLITSCREENPLAYERS);
hw_state->blit_postimg_screens->set_num_screens(screens);
hw_state->blit_postimg_screens->set_target(static_cast<uint32_t>(vid.width), static_cast<uint32_t>(vid.height));