GSDX: Pass total height of framebuffer on GetOutput()

Some PSX games seem to store image data of the drawing results in an undeterminate area out of range from the current context buffer. At such cases, calculate the height of both the frame memory rectangles combined.

What happens on "Crash bash" -

* At first draw, scissoring is limited to SCAY0- 0 & SCAY1- 255
* At second draw, scissoring is limited to SCAY0- 255 & SCAY0-511

Previously, we limited the height to the value of one single output texture, so instead of that let's calculate the total height of both the two buffers combined to prevent such issues.
This commit is contained in:
Akash 2016-12-12 13:30:25 +05:30
parent 98e8d93fa3
commit 09c72375ab
6 changed files with 19 additions and 4 deletions

View File

@ -169,7 +169,7 @@ GSTexture* GSRendererCL::GetOutput(int i, int& y_offset)
const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;
int w = DISPFB.FBW * 64;
int h = GetFrameRect(i).height();
int h = GetFramebufferHeight();
// TODO: round up bottom

View File

@ -345,7 +345,7 @@ GSTexture* GSRendererCS::GetOutput(int i, int& y_offset)
const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;
int w = DISPFB.FBW * 64;
int h = GetFrameRect(i).height();
int h = GetFramebufferHeight();
// TODO: round up bottom

View File

@ -219,7 +219,7 @@ GSTexture* GSRendererHW::GetOutput(int i, int& y_offset)
GSTexture* t = NULL;
if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GetFrameRect(i).height()))
if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GetFramebufferHeight()))
{
t = rt->m_texture;

View File

@ -165,7 +165,7 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;
int w = DISPFB.FBW * 64;
int h = GetFrameRect(i).height();
int h = GetFramebufferHeight();
// TODO: round up bottom

View File

@ -473,6 +473,20 @@ GSVector4i GSState::GetFrameRect(int i)
return rectangle;
}
int GSState::GetFramebufferHeight()
{
const GSVector4i output[2] = { GetFrameRect(0), GetFrameRect(1) };
// Framebuffer height is 11 bits max according to GS user manual
const int height_limit = (1 << 11);
int max_height = std::max(output[0].height(), output[1].height());
int frame_memory_height = std::max(max_height, output[0].runion_ordered(output[1]).height() % height_limit);
if (frame_memory_height > 1024)
GL_PERF("Massive framebuffer height detected! (height:%d)", frame_memory_height);
return frame_memory_height;
}
bool GSState::IsEnabled(int i)
{
ASSERT(i >= 0 && i < 2);

View File

@ -242,6 +242,7 @@ public:
void ResetHandlers();
int GetFramebufferHeight();
GSVector4i GetDisplayRect(int i = -1, bool merged_rect = false);
GSVector4i GetFrameRect(int i = -1);
GSVideoMode GetVideoMode();