video_core: support framebuffer crop rect top not zero

This commit is contained in:
vonchenplus 2022-08-20 16:58:01 +08:00
parent e9b7263cfd
commit 0a8c5c8622
2 changed files with 25 additions and 12 deletions

View file

@ -478,13 +478,16 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
} }
} }
ASSERT_MSG(framebuffer_crop_rect.top == 0, "Unimplemented");
ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented"); ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented");
f32 left_start{};
if (framebuffer_crop_rect.Top() > 0) {
left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
static_cast<f32>(framebuffer_crop_rect.Bottom());
}
f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width); f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width);
f32 scale_v = f32 scale_v =
static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height); static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height);
// Scale the output by the crop width/height. This is commonly used with 1280x720 rendering // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
// (e.g. handheld mode) on a 1920x1080 framebuffer. // (e.g. handheld mode) on a 1920x1080 framebuffer.
if (framebuffer_crop_rect.GetWidth() > 0) { if (framebuffer_crop_rect.GetWidth() > 0) {
@ -503,10 +506,14 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
const auto& screen = layout.screen; const auto& screen = layout.screen;
const std::array vertices = { const std::array vertices = {
ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u, left * scale_v), ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u,
ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u, left * scale_v), left_start + left * scale_v),
ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u, right * scale_v), ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u,
ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u, right * scale_v), left_start + left * scale_v),
ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u,
left_start + right * scale_v),
ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u,
left_start + right * scale_v),
}; };
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));

View file

@ -1402,12 +1402,15 @@ void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig&
break; break;
} }
UNIMPLEMENTED_IF(framebuffer_crop_rect.top != 0);
UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0); UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0);
f32 left_start{};
if (framebuffer_crop_rect.Top() > 0) {
left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
static_cast<f32>(framebuffer_crop_rect.Bottom());
}
f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width); f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width);
f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height); f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height);
// Scale the output by the crop width/height. This is commonly used with 1280x720 rendering // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
// (e.g. handheld mode) on a 1920x1080 framebuffer. // (e.g. handheld mode) on a 1920x1080 framebuffer.
if (!fsr) { if (!fsr) {
@ -1426,10 +1429,13 @@ void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig&
const auto y = static_cast<f32>(screen.top); const auto y = static_cast<f32>(screen.top);
const auto w = static_cast<f32>(screen.GetWidth()); const auto w = static_cast<f32>(screen.GetWidth());
const auto h = static_cast<f32>(screen.GetHeight()); const auto h = static_cast<f32>(screen.GetHeight());
data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v); data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left_start + left * scale_v);
data.vertices[1] = ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v); data.vertices[1] =
data.vertices[2] = ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v); ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left_start + left * scale_v);
data.vertices[3] = ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v); data.vertices[2] =
ScreenRectVertex(x, y + h, texcoords.top * scale_u, left_start + right * scale_v);
data.vertices[3] =
ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, left_start + right * scale_v);
} }
void BlitScreen::CreateFSR() { void BlitScreen::CreateFSR() {