Exemple #1
0
void GSRendererHW::SetScaling()
{
	GSVector2i crtc_size(GetDisplayRect().width(), GetDisplayRect().height());

	// Framebuffer width is always a multiple of 64 so at certain cases it can't cover some weird width values.
	// 480P , 576P use width as 720 which is not referencable by FBW * 64. so it produces 704 ( the closest value multiple by 64).
	// In such cases, let's just use the CRTC width.
	int fb_width = max({ (int)m_context->FRAME.FBW * 64, crtc_size.x , 512 });
	// GS doesn't have a specific register for the FrameBuffer height. so we get the height
	// from physical units of the display rectangle in case the game uses a heigher value of height.
	int fb_height = (fb_width < 1024) ? max(512, crtc_size.y) : 1024;

	int upscaled_fb_w = fb_width * m_upscale_multiplier;
	int upscaled_fb_h = fb_height * m_upscale_multiplier;
	bool good_rt_size = m_width >= upscaled_fb_w && m_height >= upscaled_fb_h;

	// No need to resize for native/custom resolutions as default size will be enough for native and we manually get RT Buffer size for custom.
	// don't resize until the display rectangle and register states are stabilized.
	if ( m_upscale_multiplier <= 1 || good_rt_size)
		return;

	m_tc->RemovePartial();
	m_width = upscaled_fb_w;
	m_height = upscaled_fb_h;
	printf("Frame buffer size set to  %dx%d (%dx%d)\n", fb_width, fb_height , m_width, m_height);
}
Exemple #2
0
void GSRendererHW::SetScaling()
{
	GSVector2i crtc_size(GetDisplayRect().width(), GetDisplayRect().height());

	// Details of (potential) perf impact of a big framebuffer
	// 1/ extra memory
	// 2/ texture cache framebuffer rescaling/copy
	// 3/ upload of framebuffer (preload hack)
	// 4/ framebuffer clear (color/depth/stencil)
	// 5/ read back of the frambuffer
	// 6/ MSAA
	//
	// With the solution
	// 1/ Nothing to do.Except the texture cache bug (channel shuffle effect)
	//    most of the market is 1GB of VRAM (and soon 2GB)
	// 2/ limit rescaling/copy to the valid data of the framebuffer
	// 3/ ??? no solution so far
	// 4a/ stencil can be limited to valid data.
	// 4b/ is it useful to clear color? depth? (in any case, it ought to be few operation)
	// 5/ limit the read to the valid data
	// 6/ not support on openGL

	// Framebuffer width is always a multiple of 64 so at certain cases it can't cover some weird width values.
	// 480P , 576P use width as 720 which is not referencable by FBW * 64. so it produces 704 ( the closest value multiple by 64).
	// In such cases, let's just use the CRTC width.
	int fb_width = max({ (int)m_context->FRAME.FBW * 64, crtc_size.x , 512 });
	// GS doesn't have a specific register for the FrameBuffer height. so we get the height
	// from physical units of the display rectangle in case the game uses a heigher value of height.
	//
	// Gregory: the framebuffer must have enough room to draw
	// * at least 2 frames such as FMV (see OI_BlitFMV)
	// * high resolution game such as snowblind engine game
	//
	// Autodetection isn't a good idea because it will create flickering
	// If memory consumption is an issue, there are 2 possibilities
	// * 1/ Avoid to create hundreds of RT
	// * 2/ Use sparse texture (requires recent HW)
	//
	// Avoid to alternate between 640x1280 and 1280x1024 on snow blind engine game
	// int fb_height = (fb_width < 1024) ? 1280 : 1024;
	//
	// Until performance issue is properly fixed, let's keep an option to reduce the framebuffer size.
	int fb_height = m_large_framebuffer ? 1280 :
		(fb_width < 1024) ? max(512, crtc_size.y) : 1024;

	int upscaled_fb_w = fb_width * m_upscale_multiplier;
	int upscaled_fb_h = fb_height * m_upscale_multiplier;
	bool good_rt_size = m_width >= upscaled_fb_w && m_height >= upscaled_fb_h;
	bool initialized_register_state = (m_context->FRAME.FBW > 1) && (crtc_size.y > 1);

	if (!m_upscale_multiplier && initialized_register_state)
	{
		if (m_height == m_custom_height)
		{
			float ratio = ceil(static_cast<float>(m_height) / crtc_size.y);
			float buffer_scale_offset = (m_large_framebuffer) ? ratio : 0.5f;
			ratio = round(ratio + buffer_scale_offset);

			m_tc->RemovePartial();
			m_width = max(m_width, 1280);
			m_height = max(static_cast<int>(crtc_size.y * ratio) , 1024);
		}
	}

	// No need to resize for native/custom resolutions as default size will be enough for native and we manually get RT Buffer size for custom.
	// don't resize until the display rectangle and register states are stabilized.
	if ( m_upscale_multiplier <= 1 || good_rt_size)
		return;

	m_tc->RemovePartial();
	m_width = upscaled_fb_w;
	m_height = upscaled_fb_h;
	printf("Frame buffer size set to  %dx%d (%dx%d)\n", fb_width, fb_height , m_width, m_height);
}