GSdx-HW: Remove inefficient scaling algorithm

Only impacts custom resolution, there used to be a much weaker algorithm
which doens't consider scissor sizes and gives a minor performance boost
in costs of accuracy (which was used when large framebuffer was disabled
in custom resolutions)

I've removed this as the performance tradeoff is rather negligible after
the implementation of #1942 and the older one is no longer necessary.
Also added an extra parameter for considering the horizontal scissor,
I'm not sure where this might be useful so this is disabled in code for
now till I discover a testcase where this helps or run it on random data
ensuring it's working properly.

Also porting this to the general scaling function might help with memory
spikes which are experienced when large framebuffer is enabled.
This commit is contained in:
Akash 2018-09-27 15:34:26 +05:30
parent 122871654e
commit dce6d3f451
1 changed files with 18 additions and 29 deletions

View File

@ -140,47 +140,36 @@ void GSRendererHW::CustomResolutionScaling()
{
const int crtc_width = GetDisplayRect().width();
const int crtc_height = GetDisplayRect().height();
const float scaling_ratio = std::ceil(static_cast<float>(m_custom_height) / crtc_height);
GSVector2 scaling_ratio;
scaling_ratio.x = std::ceil(static_cast<float>(m_custom_width) / crtc_width);
scaling_ratio.y = std::ceil(static_cast<float>(m_custom_height) / crtc_height);
// Avoid using a scissor value which is too high, developers can even leave the scissor to max (2047)
// at some cases when they don't want to limit the rendering size. Our assumption is that developers
// set the scissor to the actual data in the buffer. Let's use the scissoring value only at such cases
const int scissor_width = std::min(640, static_cast<int>(m_context->SCISSOR.SCAX1 - m_context->SCISSOR.SCAX0) + 1);
const int scissor_height = std::min(640, static_cast<int>(m_context->SCISSOR.SCAY1 - m_context->SCISSOR.SCAY0) + 1);
const int single_buffer_size = std::max(GetDisplayRect().height(), scissor_height);
// We have two contexts of framebuffer height -
// One for lower memory consumption and low accuracy
// Another one for higher memory consumption at necessary scenarios for higher accuracy
std::array<int, 2> framebuffer_height;
// When Large Framebuffer is disabled - Let's only consider the height of the display rectangle
// as the base (This is wrong implementation when we consider it theoretically as CRTC has no relation
// to the Framebuffer size)
framebuffer_height[0] = static_cast<int>(std::round((crtc_height * scaling_ratio)));
// When Large Framebuffer is enabled - We also consider for potential scissor sizes which are around
GSVector2i scissored_buffer_size;
//TODO: SCAX is not used yet, not sure if it's worth considering the horizontal scissor? dunno where it helps yet.
// the ICO testcase is there to show that vertical scissor is helpful on the double scan mode games.
scissored_buffer_size.x = std::max(crtc_width, scissor_width);
scissored_buffer_size.y = std::max(crtc_height, scissor_height);
// We also consider for potential scissor sizes which are around
// the size of the actual image data stored. (Helps ICO to properly scale to right size by help of the
// scissoring values) Display rectangle has a height of 256 but scissor has a height of 512 which seems to
// be the real buffer size.
framebuffer_height[1] = static_cast<int>(std::round(single_buffer_size * scaling_ratio));
// be the real buffer size. Not sure if the width one is needed, need to check it on some random data before enabling it.
// int framebuffer_width = static_cast<int>(std::round(scissored_buffer_size.x * scaling_ratio.x));
int framebuffer_height = static_cast<int>(std::round(scissored_buffer_size.y * scaling_ratio.y));
if (m_width >= m_custom_width && m_height >= framebuffer_height[m_large_framebuffer])
if (m_width >= m_custom_width && m_height >= framebuffer_height)
return;
m_tc->RemovePartial();
m_width = std::max(m_width, default_rt_size.x);
m_height = std::max(framebuffer_height[m_large_framebuffer], default_rt_size.y);
std::string overhead = std::to_string(framebuffer_height[1] - framebuffer_height[0]);
std::string message = "(Custom resolution) Framebuffer size set to " + std::to_string(crtc_width) + "x" + std::to_string(crtc_height);
message += " (" + std::to_string(m_width) + "x" + std::to_string(m_height) + ")\n";
if (m_large_framebuffer)
{
message += "Additional " + overhead + " pixels overhead by enabling Large Framebuffer\n";
}
else
{
message += "Saved " + overhead + " pixels overhead by disabling Large Framebuffer\n";
}
printf("%s", message.c_str());
m_height = std::max(framebuffer_height, default_rt_size.y);
printf("Frame buffer size set to %dx%d (%dx%d)\n", scissored_buffer_size.x, scissored_buffer_size.y, m_width, m_height);
}
GSRendererHW::~GSRendererHW()