mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-22 16:25:39 +00:00
GPU: Use full display rect for postfx calculations
This commit is contained in:
parent
4f16cb61b4
commit
b2ca23e9da
|
@ -1095,12 +1095,14 @@ void GPU::UpdateCommandTickEvent()
|
||||||
void GPU::ConvertScreenCoordinatesToDisplayCoordinates(float window_x, float window_y, float* display_x,
|
void GPU::ConvertScreenCoordinatesToDisplayCoordinates(float window_x, float window_y, float* display_x,
|
||||||
float* display_y) const
|
float* display_y) const
|
||||||
{
|
{
|
||||||
const GSVector4i draw_rc =
|
GSVector4i display_rc, draw_rc;
|
||||||
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(), true, true);
|
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(), true, true, &display_rc, &draw_rc);
|
||||||
|
|
||||||
// convert coordinates to active display region, then to full display region
|
// convert coordinates to active display region, then to full display region
|
||||||
const float scaled_display_x = (window_x - static_cast<float>(draw_rc.left)) / static_cast<float>(draw_rc.width());
|
const float scaled_display_x =
|
||||||
const float scaled_display_y = (window_y - static_cast<float>(draw_rc.top)) / static_cast<float>(draw_rc.height());
|
(window_x - static_cast<float>(display_rc.left)) / static_cast<float>(display_rc.width());
|
||||||
|
const float scaled_display_y =
|
||||||
|
(window_y - static_cast<float>(display_rc.top)) / static_cast<float>(display_rc.height());
|
||||||
|
|
||||||
// scale back to internal resolution
|
// scale back to internal resolution
|
||||||
*display_x = scaled_display_x * static_cast<float>(m_crtc_state.display_width);
|
*display_x = scaled_display_x * static_cast<float>(m_crtc_state.display_width);
|
||||||
|
@ -1941,12 +1943,14 @@ bool GPU::PresentDisplay()
|
||||||
{
|
{
|
||||||
FlushRender();
|
FlushRender();
|
||||||
|
|
||||||
const GSVector4i draw_rect = CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(),
|
GSVector4i display_rect;
|
||||||
!g_settings.debugging.show_vram, true);
|
GSVector4i draw_rect;
|
||||||
return RenderDisplay(nullptr, draw_rect, !g_settings.debugging.show_vram);
|
CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(), !g_settings.debugging.show_vram,
|
||||||
|
true, &display_rect, &draw_rect);
|
||||||
|
return RenderDisplay(nullptr, display_rect, draw_rect, !g_settings.debugging.show_vram);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool postfx)
|
bool GPU::RenderDisplay(GPUTexture* target, const GSVector4i display_rect, const GSVector4i draw_rect, bool postfx)
|
||||||
{
|
{
|
||||||
GL_SCOPE_FMT("RenderDisplay: {}", draw_rect);
|
GL_SCOPE_FMT("RenderDisplay: {}", draw_rect);
|
||||||
|
|
||||||
|
@ -2105,7 +2109,7 @@ bool GPU::RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool pos
|
||||||
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
|
const s32 orig_height = static_cast<s32>(std::ceil(static_cast<float>(m_crtc_state.display_height) * upscale_y));
|
||||||
|
|
||||||
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), nullptr, target,
|
return PostProcessing::DisplayChain.Apply(PostProcessing::DisplayChain.GetInputTexture(), nullptr, target,
|
||||||
real_draw_rect, orig_width, orig_height, m_crtc_state.display_width,
|
display_rect, orig_width, orig_height, m_crtc_state.display_width,
|
||||||
m_crtc_state.display_height);
|
m_crtc_state.display_height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2339,8 +2343,8 @@ bool GPU::ApplyChromaSmoothing()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSVector4i GPU::CalculateDrawRect(s32 window_width, s32 window_height, bool apply_rotation,
|
void GPU::CalculateDrawRect(s32 window_width, s32 window_height, bool apply_rotation, bool apply_aspect_ratio,
|
||||||
bool apply_aspect_ratio) const
|
GSVector4i* display_rect, GSVector4i* draw_rect) const
|
||||||
{
|
{
|
||||||
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
const bool integer_scale = (g_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
||||||
g_settings.display_scaling == DisplayScalingMode::BilinearInteger);
|
g_settings.display_scaling == DisplayScalingMode::BilinearInteger);
|
||||||
|
@ -2450,7 +2454,9 @@ GSVector4i GPU::CalculateDrawRect(s32 window_width, s32 window_height, bool appl
|
||||||
const s32 top = static_cast<s32>(active_top * scale + top_padding);
|
const s32 top = static_cast<s32>(active_top * scale + top_padding);
|
||||||
const s32 right = left + static_cast<s32>(active_width * scale);
|
const s32 right = left + static_cast<s32>(active_width * scale);
|
||||||
const s32 bottom = top + static_cast<s32>(active_height * scale);
|
const s32 bottom = top + static_cast<s32>(active_height * scale);
|
||||||
return GSVector4i(left, top, right, bottom);
|
*draw_rect = GSVector4i(left, top, right, bottom);
|
||||||
|
*display_rect = GSVector4i(
|
||||||
|
GSVector4(left_padding, top_padding, left_padding + display_width * scale, top_padding + display_height * scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
bool CompressAndWriteTextureToFile(u32 width, u32 height, std::string filename, FileSystem::ManagedCFilePtr fp,
|
||||||
|
@ -2622,8 +2628,9 @@ bool GPU::WriteDisplayTextureToFile(std::string filename, bool compress_on_threa
|
||||||
flip_y, std::move(texture_data), texture_data_stride, m_display_texture->GetFormat(), false, compress_on_thread);
|
flip_y, std::move(texture_data), texture_data_stride, m_display_texture->GetFormat(), false, compress_on_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_rect, bool postfx,
|
bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i display_rect, const GSVector4i draw_rect,
|
||||||
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format)
|
bool postfx, std::vector<u32>* out_pixels, u32* out_stride,
|
||||||
|
GPUTexture::Format* out_format)
|
||||||
{
|
{
|
||||||
const GPUTexture::Format hdformat =
|
const GPUTexture::Format hdformat =
|
||||||
g_gpu_device->HasSurface() ? g_gpu_device->GetWindowFormat() : GPUTexture::Format::RGBA8;
|
g_gpu_device->HasSurface() ? g_gpu_device->GetWindowFormat() : GPUTexture::Format::RGBA8;
|
||||||
|
@ -2636,7 +2643,7 @@ bool GPU::RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_
|
||||||
g_gpu_device->ClearRenderTarget(render_texture.get(), GPUDevice::DEFAULT_CLEAR_COLOR);
|
g_gpu_device->ClearRenderTarget(render_texture.get(), GPUDevice::DEFAULT_CLEAR_COLOR);
|
||||||
|
|
||||||
// TODO: this should use copy shader instead.
|
// TODO: this should use copy shader instead.
|
||||||
RenderDisplay(render_texture.get(), draw_rect, postfx);
|
RenderDisplay(render_texture.get(), display_rect, draw_rect, postfx);
|
||||||
|
|
||||||
const u32 stride = Common::AlignUpPow2(GPUTexture::GetPixelSize(hdformat) * width, sizeof(u32));
|
const u32 stride = Common::AlignUpPow2(GPUTexture::GetPixelSize(hdformat) * width, sizeof(u32));
|
||||||
out_pixels->resize((height * stride) / sizeof(u32));
|
out_pixels->resize((height * stride) / sizeof(u32));
|
||||||
|
@ -2674,7 +2681,8 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
{
|
{
|
||||||
u32 width = g_gpu_device->GetWindowWidth();
|
u32 width = g_gpu_device->GetWindowWidth();
|
||||||
u32 height = g_gpu_device->GetWindowHeight();
|
u32 height = g_gpu_device->GetWindowHeight();
|
||||||
GSVector4i draw_rect = CalculateDrawRect(width, height, true, !g_settings.debugging.show_vram);
|
GSVector4i display_rect, draw_rect;
|
||||||
|
CalculateDrawRect(width, height, true, !g_settings.debugging.show_vram, &display_rect, &draw_rect);
|
||||||
|
|
||||||
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution || g_settings.debugging.show_vram);
|
const bool internal_resolution = (mode != DisplayScreenshotMode::ScreenResolution || g_settings.debugging.show_vram);
|
||||||
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
if (internal_resolution && m_display_texture_view_width != 0 && m_display_texture_view_height != 0)
|
||||||
|
@ -2727,6 +2735,7 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
|
|
||||||
// Remove padding, it's not part of the framebuffer.
|
// Remove padding, it's not part of the framebuffer.
|
||||||
draw_rect = GSVector4i(0, 0, static_cast<s32>(width), static_cast<s32>(height));
|
draw_rect = GSVector4i(0, 0, static_cast<s32>(width), static_cast<s32>(height));
|
||||||
|
display_rect = draw_rect;
|
||||||
}
|
}
|
||||||
if (width == 0 || height == 0)
|
if (width == 0 || height == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -2734,7 +2743,7 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
|
||||||
std::vector<u32> pixels;
|
std::vector<u32> pixels;
|
||||||
u32 pixels_stride;
|
u32 pixels_stride;
|
||||||
GPUTexture::Format pixels_format;
|
GPUTexture::Format pixels_format;
|
||||||
if (!RenderScreenshotToBuffer(width, height, draw_rect, !internal_resolution, &pixels, &pixels_stride,
|
if (!RenderScreenshotToBuffer(width, height, display_rect, draw_rect, !internal_resolution, &pixels, &pixels_stride,
|
||||||
&pixels_format))
|
&pixels_format))
|
||||||
{
|
{
|
||||||
ERROR_LOG("Failed to render {}x{} screenshot", width, height);
|
ERROR_LOG("Failed to render {}x{} screenshot", width, height);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "gpu_types.h"
|
#include "gpu_types.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
#include "types.h"
|
|
||||||
#include "timing_event.h"
|
#include "timing_event.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include "util/gpu_texture.h"
|
#include "util/gpu_texture.h"
|
||||||
|
|
||||||
|
@ -207,14 +207,16 @@ public:
|
||||||
virtual void FlushRender() = 0;
|
virtual void FlushRender() = 0;
|
||||||
|
|
||||||
/// Helper function for computing the draw rectangle in a larger window.
|
/// Helper function for computing the draw rectangle in a larger window.
|
||||||
GSVector4i CalculateDrawRect(s32 window_width, s32 window_height, bool apply_rotation, bool apply_aspect_ratio) const;
|
void CalculateDrawRect(s32 window_width, s32 window_height, bool apply_rotation, bool apply_aspect_ratio,
|
||||||
|
GSVector4i* display_rect, GSVector4i* draw_rect) const;
|
||||||
|
|
||||||
/// Helper function to save current display texture to PNG.
|
/// Helper function to save current display texture to PNG.
|
||||||
bool WriteDisplayTextureToFile(std::string filename, bool compress_on_thread = false);
|
bool WriteDisplayTextureToFile(std::string filename, bool compress_on_thread = false);
|
||||||
|
|
||||||
/// Renders the display, optionally with postprocessing to the specified image.
|
/// Renders the display, optionally with postprocessing to the specified image.
|
||||||
bool RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i draw_rect, bool postfx,
|
bool RenderScreenshotToBuffer(u32 width, u32 height, const GSVector4i display_rect, const GSVector4i draw_rect,
|
||||||
std::vector<u32>* out_pixels, u32* out_stride, GPUTexture::Format* out_format);
|
bool postfx, std::vector<u32>* out_pixels, u32* out_stride,
|
||||||
|
GPUTexture::Format* out_format);
|
||||||
|
|
||||||
/// Helper function to save screenshot to PNG.
|
/// Helper function to save screenshot to PNG.
|
||||||
bool RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mode, u8 quality, bool compress_on_thread,
|
bool RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mode, u8 quality, bool compress_on_thread,
|
||||||
|
@ -343,8 +345,7 @@ protected:
|
||||||
|
|
||||||
AddCommandTicks(pixels);
|
AddCommandTicks(pixels);
|
||||||
}
|
}
|
||||||
ALWAYS_INLINE_RELEASE void AddDrawRectangleTicks(const GSVector4i clamped_rect, bool textured,
|
ALWAYS_INLINE_RELEASE void AddDrawRectangleTicks(const GSVector4i clamped_rect, bool textured, bool semitransparent)
|
||||||
bool semitransparent)
|
|
||||||
{
|
{
|
||||||
u32 drawn_width = clamped_rect.width();
|
u32 drawn_width = clamped_rect.width();
|
||||||
u32 drawn_height = clamped_rect.height();
|
u32 drawn_height = clamped_rect.height();
|
||||||
|
@ -591,7 +592,7 @@ protected:
|
||||||
void SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_texture, s32 view_x, s32 view_y, s32 view_width,
|
void SetDisplayTexture(GPUTexture* texture, GPUTexture* depth_texture, s32 view_x, s32 view_y, s32 view_width,
|
||||||
s32 view_height);
|
s32 view_height);
|
||||||
|
|
||||||
bool RenderDisplay(GPUTexture* target, const GSVector4i draw_rect, bool postfx);
|
bool RenderDisplay(GPUTexture* target, const GSVector4i display_rect, const GSVector4i draw_rect, bool postfx);
|
||||||
|
|
||||||
bool Deinterlace(u32 field, u32 line_skip);
|
bool Deinterlace(u32 field, u32 line_skip);
|
||||||
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
bool DeinterlaceExtractField(u32 dst_bufidx, GPUTexture* src, u32 x, u32 y, u32 width, u32 height, u32 line_skip);
|
||||||
|
|
|
@ -2869,19 +2869,22 @@ bool System::SaveStateToBuffer(SaveStateBuffer* buffer, Error* error, u32 screen
|
||||||
if (screenshot_size > 0)
|
if (screenshot_size > 0)
|
||||||
{
|
{
|
||||||
// assume this size is the width
|
// assume this size is the width
|
||||||
const float display_aspect_ratio = g_gpu->ComputeDisplayAspectRatio();
|
GSVector4i screenshot_display_rect, screenshot_draw_rect;
|
||||||
const u32 screenshot_width = screenshot_size;
|
g_gpu->CalculateDrawRect(screenshot_size, screenshot_size, true, true, &screenshot_display_rect,
|
||||||
const u32 screenshot_height =
|
&screenshot_draw_rect);
|
||||||
std::max(1u, static_cast<u32>(static_cast<float>(screenshot_width) /
|
|
||||||
((display_aspect_ratio > 0.0f) ? display_aspect_ratio : 1.0f)));
|
const u32 screenshot_width = static_cast<u32>(screenshot_display_rect.width());
|
||||||
|
const u32 screenshot_height = static_cast<u32>(screenshot_display_rect.height());
|
||||||
|
screenshot_draw_rect = screenshot_draw_rect.sub32(screenshot_display_rect.xyxy());
|
||||||
|
screenshot_display_rect = screenshot_display_rect.sub32(screenshot_display_rect.xyxy());
|
||||||
VERBOSE_LOG("Saving {}x{} screenshot for state", screenshot_width, screenshot_height);
|
VERBOSE_LOG("Saving {}x{} screenshot for state", screenshot_width, screenshot_height);
|
||||||
|
|
||||||
std::vector<u32> screenshot_buffer;
|
std::vector<u32> screenshot_buffer;
|
||||||
u32 screenshot_stride;
|
u32 screenshot_stride;
|
||||||
GPUTexture::Format screenshot_format;
|
GPUTexture::Format screenshot_format;
|
||||||
if (g_gpu->RenderScreenshotToBuffer(screenshot_width, screenshot_height,
|
if (g_gpu->RenderScreenshotToBuffer(screenshot_width, screenshot_height, screenshot_display_rect,
|
||||||
GSVector4i(0, 0, screenshot_width, screenshot_height), false,
|
screenshot_draw_rect, false, &screenshot_buffer, &screenshot_stride,
|
||||||
&screenshot_buffer, &screenshot_stride, &screenshot_format) &&
|
&screenshot_format) &&
|
||||||
GPUTexture::ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
|
GPUTexture::ConvertTextureDataToRGBA8(screenshot_width, screenshot_height, screenshot_buffer, screenshot_stride,
|
||||||
screenshot_format))
|
screenshot_format))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue