mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-22 12:39:52 +00:00
rsx: Resolution scaling overhaul
- Enforce square pixels instead of per-axis scaling
This commit is contained in:
parent
68931b4c43
commit
0e7a705254
@ -85,10 +85,14 @@ namespace rsx
|
||||
if (g_cfg.video.resolution_scale_percent != 100)
|
||||
{
|
||||
auto src = static_cast<T>(source);
|
||||
src_w = rsx::apply_resolution_scale(src_w, true, src->get_surface_width(rsx::surface_metrics::pixels));
|
||||
src_h = rsx::apply_resolution_scale(src_h, true, src->get_surface_height(rsx::surface_metrics::pixels));
|
||||
dst_w = rsx::apply_resolution_scale(dst_w, true, target_surface->get_surface_width(rsx::surface_metrics::pixels));
|
||||
dst_h = rsx::apply_resolution_scale(dst_h, true, target_surface->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
std::tie(src_w, src_h) = rsx::apply_resolution_scale<true>(src_w, src_h,
|
||||
src->get_surface_width(rsx::surface_metrics::pixels),
|
||||
src->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
std::tie(dst_w, dst_h) = rsx::apply_resolution_scale<true>(dst_w, dst_h,
|
||||
target_surface->get_surface_width(rsx::surface_metrics::pixels),
|
||||
target_surface->get_surface_height(rsx::surface_metrics::pixels));
|
||||
}
|
||||
|
||||
width = src_w;
|
||||
@ -484,11 +488,8 @@ namespace rsx
|
||||
// Apply resolution scale if needed
|
||||
if (g_cfg.video.resolution_scale_percent != 100)
|
||||
{
|
||||
auto src_width = rsx::apply_resolution_scale(slice.width, true, slice.source->width());
|
||||
auto src_height = rsx::apply_resolution_scale(slice.height, true, slice.source->height());
|
||||
|
||||
auto dst_width = rsx::apply_resolution_scale(slice.width, true, slice.target->width());
|
||||
auto dst_height = rsx::apply_resolution_scale(slice.height, true, slice.target->height());
|
||||
auto [src_width, src_height] = rsx::apply_resolution_scale<true>(slice.width, slice.height, slice.source->width(), slice.source->height());
|
||||
auto [dst_width, dst_height] = rsx::apply_resolution_scale<true>(slice.width, slice.height, slice.target->width(), slice.target->height());
|
||||
|
||||
slice.transfer_scale_x *= f32(dst_width) / src_width;
|
||||
slice.transfer_scale_y *= f32(dst_height) / src_height;
|
||||
@ -496,10 +497,8 @@ namespace rsx
|
||||
slice.width = src_width;
|
||||
slice.height = src_height;
|
||||
|
||||
slice.src_x = rsx::apply_resolution_scale(slice.src_x, false, slice.source->width());
|
||||
slice.src_y = rsx::apply_resolution_scale(slice.src_y, false, slice.source->height());
|
||||
slice.dst_x = rsx::apply_resolution_scale(slice.dst_x, false, slice.target->width());
|
||||
slice.dst_y = rsx::apply_resolution_scale(slice.dst_y, false, slice.target->height());
|
||||
std::tie(slice.src_x, slice.src_y) = rsx::apply_resolution_scale<false>(slice.src_x, slice.src_y, slice.source->width(), slice.source->height());
|
||||
std::tie(slice.dst_x, slice.dst_y) = rsx::apply_resolution_scale<false>(slice.dst_x, slice.dst_y, slice.target->width(), slice.target->height());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,8 +287,8 @@ namespace rsx
|
||||
|
||||
// How much of this slice to read?
|
||||
int rebased = int(section.dst_area.y) - slice_begin;
|
||||
const auto src_x = section.src_area.x;
|
||||
const auto dst_x = section.dst_area.x;
|
||||
auto src_x = section.src_area.x;
|
||||
auto dst_x = section.dst_area.x;
|
||||
auto src_y = section.src_area.y;
|
||||
auto dst_y = section.dst_area.y;
|
||||
|
||||
@ -306,20 +306,22 @@ namespace rsx
|
||||
const auto h = std::min(section_end, slice_end) - dst_y;
|
||||
dst_y = (dst_y - slice_begin);
|
||||
|
||||
const auto src_width = rsx::apply_resolution_scale(section.src_area.width, true);
|
||||
const auto src_height = rsx::apply_resolution_scale(h, true);
|
||||
const auto dst_width = rsx::apply_resolution_scale(section.dst_area.width, true);
|
||||
const auto [src_width, src_height] = rsx::apply_resolution_scale<true>(section.src_area.width, h, attr.width, attr.height);
|
||||
const auto [dst_width, unused] = rsx::apply_resolution_scale<true>(section.dst_area.width, RSX_SURFACE_DIMENSION_IGNORED, attr.width, RSX_SURFACE_DIMENSION_IGNORED);
|
||||
const auto dst_height = src_height;
|
||||
|
||||
std::tie(src_x, src_y) = rsx::apply_resolution_scale<false>(src_x, src_y, attr.width, attr.height);
|
||||
std::tie(dst_x, dst_y) = rsx::apply_resolution_scale<false>(dst_x, dst_y, attr.width, attr.height);
|
||||
|
||||
out.push_back
|
||||
({
|
||||
section.surface->get_surface(rsx::surface_access::read),
|
||||
surface_transform::identity,
|
||||
0,
|
||||
rsx::apply_resolution_scale(src_x, true),
|
||||
rsx::apply_resolution_scale(src_y, true),
|
||||
rsx::apply_resolution_scale(dst_x, true),
|
||||
rsx::apply_resolution_scale(dst_y, true),
|
||||
static_cast<u16>(src_x),
|
||||
static_cast<u16>(src_y),
|
||||
static_cast<u16>(dst_x),
|
||||
static_cast<u16>(dst_y),
|
||||
slice,
|
||||
src_width, src_height,
|
||||
dst_width, dst_height
|
||||
@ -365,6 +367,9 @@ namespace rsx
|
||||
if (scaling)
|
||||
{
|
||||
// Since output is upscaled, also upscale on dst
|
||||
const auto [_dst_x, _dst_y] = rsx::apply_resolution_scale<false>(static_cast<u16>(std::get<1>(clipped).x), static_cast<u16>(dst_y - slice_begin), attr.width, attr.height);
|
||||
const auto [_dst_w, _dst_h] = rsx::apply_resolution_scale<true>(dst_w, height, attr.width, attr.height);
|
||||
|
||||
out.push_back
|
||||
({
|
||||
section->get_raw_texture(),
|
||||
@ -372,13 +377,13 @@ namespace rsx
|
||||
0,
|
||||
static_cast<u16>(std::get<0>(clipped).x), // src.x
|
||||
static_cast<u16>(std::get<0>(clipped).y), // src.y
|
||||
rsx::apply_resolution_scale(static_cast<u16>(std::get<1>(clipped).x), true), // dst.x
|
||||
rsx::apply_resolution_scale(static_cast<u16>(dst_y - slice_begin), true), // dst.y
|
||||
_dst_x, // dst.x
|
||||
_dst_y, // dst.y
|
||||
slice,
|
||||
src_w,
|
||||
height,
|
||||
rsx::apply_resolution_scale(dst_w, true),
|
||||
rsx::apply_resolution_scale(height, true),
|
||||
_dst_w,
|
||||
_dst_h,
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -539,8 +544,7 @@ namespace rsx
|
||||
attr2.height < surface_height ||
|
||||
force_convert)
|
||||
{
|
||||
const auto scaled_w = rsx::apply_resolution_scale(attr2.width, true);
|
||||
const auto scaled_h = rsx::apply_resolution_scale(attr2.height, true);
|
||||
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(attr2.width, attr2.height);
|
||||
|
||||
const auto format_class = (force_convert) ? classify_format(attr2.gcm_format) : texptr->format_class();
|
||||
const auto command = surface_is_rop_target ? deferred_request_command::copy_image_dynamic : deferred_request_command::copy_image_static;
|
||||
@ -557,8 +561,7 @@ namespace rsx
|
||||
texptr->format_class(), scale, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target };
|
||||
}
|
||||
|
||||
const auto scaled_w = rsx::apply_resolution_scale(attr2.width, true);
|
||||
const auto scaled_h = rsx::apply_resolution_scale(attr2.height, true);
|
||||
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(attr2.width, attr2.height);
|
||||
|
||||
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_3d)
|
||||
{
|
||||
@ -643,8 +646,7 @@ namespace rsx
|
||||
}
|
||||
|
||||
// If this method was called, there is no easy solution, likely means atlas gather is needed
|
||||
auto scaled_w = rsx::apply_resolution_scale(attr2.width, true);
|
||||
auto scaled_h = rsx::apply_resolution_scale(attr2.height, true);
|
||||
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale(attr2.width, attr2.height);
|
||||
const auto format_class = classify_format(attr2.gcm_format);
|
||||
|
||||
if (extended_dimension == rsx::texture_dimension_extended::texture_dimension_cubemap)
|
||||
@ -717,8 +719,7 @@ namespace rsx
|
||||
// Calculate transfer dimensions from attr
|
||||
if (level.upload_context == rsx::texture_upload_context::framebuffer_storage) [[likely]]
|
||||
{
|
||||
mip.src_w = rsx::apply_resolution_scale(attr.width, true);
|
||||
mip.src_h = rsx::apply_resolution_scale(attr.height, true);
|
||||
std::tie(mip.src_w, mip.src_h) = rsx::apply_resolution_scale<true>(attr.width, attr.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -763,8 +764,7 @@ namespace rsx
|
||||
if (apply_upscaling)
|
||||
{
|
||||
auto& mip = sections.back();
|
||||
mip.dst_w = rsx::apply_resolution_scale(mip.dst_w, true, level0_attr.width);
|
||||
mip.dst_h = rsx::apply_resolution_scale(mip.dst_h, true, level0_attr.height);
|
||||
std::tie(mip.dst_w, mip.dst_h) = rsx::apply_resolution_scale<true>(mip.dst_w, mip.dst_h, level0_attr.width, level0_attr.height);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -32,8 +32,9 @@ extern CellGcmContextData current_context;
|
||||
void GLGSRender::set_viewport()
|
||||
{
|
||||
// NOTE: scale offset matrix already contains the viewport transformation
|
||||
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
||||
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
||||
const auto [clip_width, clip_height] = rsx::apply_resolution_scale<true>(
|
||||
rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height());
|
||||
|
||||
glViewport(0, 0, clip_width, clip_height);
|
||||
}
|
||||
|
||||
|
@ -48,8 +48,9 @@ gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, cons
|
||||
surface->read_barrier(cmd);
|
||||
image = section.surface->get_surface(rsx::surface_access::read);
|
||||
|
||||
info->width = rsx::apply_resolution_scale(std::min(surface_width, static_cast<u16>(info->width)), true);
|
||||
info->height = rsx::apply_resolution_scale(std::min(surface_height, static_cast<u16>(info->height)), true);
|
||||
std::tie(info->width, info->height) = rsx::apply_resolution_scale<true>(
|
||||
std::min(surface_width, static_cast<u16>(info->width)),
|
||||
std::min(surface_height, static_cast<u16>(info->height)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +155,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
|
||||
if (avconfig->_3d) [[unlikely]]
|
||||
{
|
||||
const auto min_expected_height = rsx::apply_resolution_scale(buffer_height + 30, true);
|
||||
const auto [unused, min_expected_height] = rsx::apply_resolution_scale<true>(RSX_SURFACE_DIMENSION_IGNORED, buffer_height + 30);
|
||||
if (image_to_flip_->height() < min_expected_height)
|
||||
{
|
||||
// Get image for second eye
|
||||
@ -168,7 +169,8 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
else
|
||||
{
|
||||
// Account for possible insets
|
||||
buffer_height = std::min<u32>(image_to_flip_->height() - min_expected_height, rsx::apply_resolution_scale(buffer_height, true));
|
||||
const auto [unused2, scaled_buffer_height] = rsx::apply_resolution_scale<true>(RSX_SURFACE_DIMENSION_IGNORED, buffer_height);
|
||||
buffer_height = std::min<u32>(image_to_flip_->height() - min_expected_height, scaled_buffer_height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,8 @@ namespace gl
|
||||
bool matches_dimensions(u16 _width, u16 _height) const
|
||||
{
|
||||
//Use forward scaling to account for rounding and clamping errors
|
||||
return (rsx::apply_resolution_scale(_width, true) == width()) && (rsx::apply_resolution_scale(_height, true) == height());
|
||||
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(_width, _height);
|
||||
return (scaled_w == width()) && (scaled_h == height());
|
||||
}
|
||||
|
||||
void memory_barrier(gl::command_context& cmd, rsx::surface_access access);
|
||||
@ -144,10 +145,10 @@ struct gl_render_target_traits
|
||||
)
|
||||
{
|
||||
auto format = rsx::internals::surface_color_format_to_gl(surface_color_format);
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
std::unique_ptr<gl::render_target> result(new gl::render_target(rsx::apply_resolution_scale(static_cast<u16>(width), true),
|
||||
rsx::apply_resolution_scale(static_cast<u16>(height), true), static_cast<GLenum>(format.internal_format),
|
||||
RSX_FORMAT_CLASS_COLOR));
|
||||
std::unique_ptr<gl::render_target> result(new gl::render_target(width_, height_,
|
||||
static_cast<GLenum>(format.internal_format), RSX_FORMAT_CLASS_COLOR));
|
||||
|
||||
result->set_aa_mode(antialias);
|
||||
result->set_native_pitch(static_cast<u16>(width) * get_format_block_size_in_bytes(surface_color_format) * result->samples_x);
|
||||
@ -173,9 +174,10 @@ struct gl_render_target_traits
|
||||
)
|
||||
{
|
||||
auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format);
|
||||
std::unique_ptr<gl::render_target> result(new gl::render_target(rsx::apply_resolution_scale(static_cast<u16>(width), true),
|
||||
rsx::apply_resolution_scale(static_cast<u16>(height), true), static_cast<GLenum>(format.internal_format),
|
||||
rsx::classify_format(surface_depth_format)));
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
std::unique_ptr<gl::render_target> result(new gl::render_target(width_, height_,
|
||||
static_cast<GLenum>(format.internal_format), rsx::classify_format(surface_depth_format)));
|
||||
|
||||
result->set_aa_mode(antialias);
|
||||
result->set_surface_dimensions(static_cast<u16>(width), static_cast<u16>(height), static_cast<u16>(pitch));
|
||||
@ -201,8 +203,8 @@ struct gl_render_target_traits
|
||||
if (!sink)
|
||||
{
|
||||
auto internal_format = static_cast<GLenum>(ref->get_internal_format());
|
||||
const auto new_w = rsx::apply_resolution_scale(prev.width, true, ref->get_surface_width(rsx::surface_metrics::pixels));
|
||||
const auto new_h = rsx::apply_resolution_scale(prev.height, true, ref->get_surface_height(rsx::surface_metrics::pixels));
|
||||
const auto [new_w, new_h] = rsx::apply_resolution_scale<true>(prev.width, prev.height,
|
||||
ref->get_surface_width(rsx::surface_metrics::pixels), ref->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
sink = std::make_unique<gl::render_target>(new_w, new_h, internal_format, ref->format_class());
|
||||
sink->add_ref();
|
||||
|
@ -1518,10 +1518,8 @@ namespace rsx
|
||||
framebuffer_status_valid = true;
|
||||
}
|
||||
|
||||
region.x1 = rsx::apply_resolution_scale(x1, false);
|
||||
region.x2 = rsx::apply_resolution_scale(x2, true);
|
||||
region.y1 = rsx::apply_resolution_scale(y1, false);
|
||||
region.y2 = rsx::apply_resolution_scale(y2, true);
|
||||
std::tie(region.x1, region.y1) = rsx::apply_resolution_scale<false>(x1, y1);
|
||||
std::tie(region.x2, region.y2) = rsx::apply_resolution_scale<true>(x2, y2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -952,8 +952,9 @@ VkDescriptorSet VKGSRender::allocate_descriptor_set()
|
||||
|
||||
void VKGSRender::set_viewport()
|
||||
{
|
||||
const auto clip_width = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_width(), true);
|
||||
const auto clip_height = rsx::apply_resolution_scale(rsx::method_registers.surface_clip_height(), true);
|
||||
const auto [clip_width, clip_height] = rsx::apply_resolution_scale<true>(
|
||||
rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height());
|
||||
|
||||
const auto zclip_near = rsx::method_registers.clip_min();
|
||||
const auto zclip_far = rsx::method_registers.clip_max();
|
||||
|
||||
@ -2187,8 +2188,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
m_cached_renderpass = vk::get_renderpass(*m_device, m_current_renderpass_key);
|
||||
|
||||
// Search old framebuffers for this same configuration
|
||||
const auto fbo_width = rsx::apply_resolution_scale(m_framebuffer_layout.width, true);
|
||||
const auto fbo_height = rsx::apply_resolution_scale(m_framebuffer_layout.height, true);
|
||||
const auto [fbo_width, fbo_height] = rsx::apply_resolution_scale<true>(m_framebuffer_layout.width, m_framebuffer_layout.height);
|
||||
|
||||
if (m_draw_fbo)
|
||||
{
|
||||
|
@ -313,8 +313,9 @@ vk::image* VKGSRender::get_present_source(vk::present_surface_info* info, const
|
||||
surface->read_barrier(*m_current_command_buffer);
|
||||
image_to_flip = section.surface->get_surface(rsx::surface_access::read);
|
||||
|
||||
info->width = rsx::apply_resolution_scale(std::min(surface_width, static_cast<u16>(info->width)), true);
|
||||
info->height = rsx::apply_resolution_scale(std::min(surface_height, static_cast<u16>(info->height)), true);
|
||||
std::tie(info->width, info->height) = rsx::apply_resolution_scale<true>(
|
||||
std::min(surface_width, static_cast<u16>(info->width)),
|
||||
std::min(surface_height, static_cast<u16>(info->height)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -469,7 +470,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
|
||||
if (avconfig->_3d) [[unlikely]]
|
||||
{
|
||||
const auto min_expected_height = rsx::apply_resolution_scale(buffer_height + 30, true);
|
||||
const auto [unused, min_expected_height] = rsx::apply_resolution_scale<true>(RSX_SURFACE_DIMENSION_IGNORED, buffer_height + 30);
|
||||
if (image_to_flip->height() < min_expected_height)
|
||||
{
|
||||
// Get image for second eye
|
||||
@ -483,7 +484,8 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
else
|
||||
{
|
||||
// Account for possible insets
|
||||
buffer_height = std::min<u32>(image_to_flip->height() - min_expected_height, rsx::apply_resolution_scale(buffer_height, true));
|
||||
const auto [unused2, scaled_buffer_height] = rsx::apply_resolution_scale<true>(RSX_SURFACE_DIMENSION_IGNORED, buffer_height);
|
||||
buffer_height = std::min<u32>(image_to_flip->height() - min_expected_height, scaled_buffer_height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,8 +345,9 @@ namespace vk
|
||||
|
||||
bool matches_dimensions(u16 _width, u16 _height) const
|
||||
{
|
||||
//Use forward scaling to account for rounding and clamping errors
|
||||
return (rsx::apply_resolution_scale(_width, true) == width()) && (rsx::apply_resolution_scale(_height, true) == height());
|
||||
// Use forward scaling to account for rounding and clamping errors
|
||||
const auto [scaled_w, scaled_h] = rsx::apply_resolution_scale<true>(_width, _height);
|
||||
return (scaled_w == width()) && (scaled_h == height());
|
||||
}
|
||||
|
||||
void texture_barrier(vk::command_buffer& cmd)
|
||||
@ -644,11 +645,13 @@ namespace rsx
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::render_target> rtt;
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
rtt = std::make_unique<vk::render_target>(device, device.get_memory_mapping().device_local,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
requested_format,
|
||||
static_cast<uint32_t>(rsx::apply_resolution_scale(static_cast<u16>(width), true)), static_cast<uint32_t>(rsx::apply_resolution_scale(static_cast<u16>(height), true)), 1, 1, 1,
|
||||
static_cast<uint32_t>(width_), static_cast<uint32_t>(height_), 1, 1, 1,
|
||||
static_cast<VkSampleCountFlagBits>(samples),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
@ -702,11 +705,13 @@ namespace rsx
|
||||
}
|
||||
|
||||
std::unique_ptr<vk::render_target> ds;
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
ds = std::make_unique<vk::render_target>(device, device.get_memory_mapping().device_local,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
requested_format,
|
||||
static_cast<uint32_t>(rsx::apply_resolution_scale(static_cast<u16>(width), true)), static_cast<uint32_t>(rsx::apply_resolution_scale(static_cast<u16>(height), true)), 1, 1, 1,
|
||||
static_cast<uint32_t>(width_), static_cast<uint32_t>(height_), 1, 1, 1,
|
||||
static_cast<VkSampleCountFlagBits>(samples),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
@ -738,8 +743,8 @@ namespace rsx
|
||||
{
|
||||
if (!sink)
|
||||
{
|
||||
const auto new_w = rsx::apply_resolution_scale(prev.width, true, ref->get_surface_width(rsx::surface_metrics::pixels));
|
||||
const auto new_h = rsx::apply_resolution_scale(prev.height, true, ref->get_surface_height(rsx::surface_metrics::pixels));
|
||||
const auto [new_w, new_h] = rsx::apply_resolution_scale<true>(prev.width, prev.height,
|
||||
ref->get_surface_width(rsx::surface_metrics::pixels), ref->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
auto& dev = cmd.get_command_pool().get_owner();
|
||||
sink = std::make_unique<vk::render_target>(dev, dev.get_memory_mapping().device_local,
|
||||
|
@ -14,6 +14,8 @@ extern "C"
|
||||
#include <libavutil/pixfmt.h>
|
||||
}
|
||||
|
||||
#define RSX_SURFACE_DIMENSION_IGNORED 1
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
// Import address_range utilities
|
||||
@ -586,33 +588,54 @@ namespace rsx
|
||||
return g_cfg.video.strict_rendering_mode ? 100 : g_cfg.video.resolution_scale_percent;
|
||||
}
|
||||
|
||||
static inline const u16 apply_resolution_scale(u16 value, bool clamp, u16 ref = 0)
|
||||
template <bool clamp = false>
|
||||
static inline const std::pair<u16, u16> apply_resolution_scale(u16 width, u16 height, u16 ref_width = 0, u16 ref_height = 0)
|
||||
{
|
||||
if (ref == 0)
|
||||
ref = value;
|
||||
|
||||
if (ref <= g_cfg.video.min_scalable_dimension)
|
||||
return value;
|
||||
|
||||
else if (clamp)
|
||||
return static_cast<u16>(std::max((get_resolution_scale_percent() * value) / 100, 1));
|
||||
u16 ref;
|
||||
if (width > height) [[likely]]
|
||||
{
|
||||
ref = (ref_width) ? ref_width : width;
|
||||
}
|
||||
else
|
||||
return static_cast<u16>((get_resolution_scale_percent() * value) / 100);
|
||||
{
|
||||
ref = (ref_height) ? ref_height : height;
|
||||
}
|
||||
|
||||
static inline const u16 apply_inverse_resolution_scale(u16 value, bool clamp)
|
||||
if (ref > g_cfg.video.min_scalable_dimension)
|
||||
{
|
||||
u16 result = value;
|
||||
// Upscale both width and height
|
||||
width = (get_resolution_scale_percent() * width) / 100;
|
||||
height = (get_resolution_scale_percent() * height) / 100;
|
||||
|
||||
if constexpr (clamp)
|
||||
{
|
||||
width = std::max<u16>(width, 1);
|
||||
height = std::max<u16>(height, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
template <bool clamp = false>
|
||||
static inline const std::pair<u16, u16> apply_inverse_resolution_scale(u16 width, u16 height)
|
||||
{
|
||||
// Inverse scale
|
||||
auto width_ = (width * 100) / get_resolution_scale_percent();
|
||||
auto height_ = (height * 100) / get_resolution_scale_percent();
|
||||
|
||||
if (clamp)
|
||||
result = static_cast<u16>(std::max((value * 100) / get_resolution_scale_percent(), 1));
|
||||
else
|
||||
result = static_cast<u16>((value * 100) / get_resolution_scale_percent());
|
||||
{
|
||||
width_ = std::max<u16>(width_, 1);
|
||||
height_ = std::max<u16>(height_, 1);
|
||||
}
|
||||
|
||||
if (result <= g_cfg.video.min_scalable_dimension)
|
||||
return value;
|
||||
if (std::max(width_, height_) > g_cfg.video.min_scalable_dimension)
|
||||
{
|
||||
return { width_, height_ };
|
||||
}
|
||||
|
||||
return result;
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user