summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvnflinger/buffer_transform_flags.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp101
2 files changed, 57 insertions, 46 deletions
diff --git a/src/core/hle/service/nvnflinger/buffer_transform_flags.h b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
index 67aa5dad6..ffe579718 100644
--- a/src/core/hle/service/nvnflinger/buffer_transform_flags.h
+++ b/src/core/hle/service/nvnflinger/buffer_transform_flags.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/common_funcs.h"
6#include "common/common_types.h" 7#include "common/common_types.h"
7 8
8namespace Service::android { 9namespace Service::android {
@@ -21,5 +22,6 @@ enum class BufferTransformFlags : u32 {
21 /// Rotate source image 270 degrees clockwise 22 /// Rotate source image 270 degrees clockwise
22 Rotate270 = 0x07, 23 Rotate270 = 0x07,
23}; 24};
25DECLARE_ENUM_FLAG_OPERATORS(BufferTransformFlags);
24 26
25} // namespace Service::android 27} // namespace Service::android
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 52fc142d1..459ab32c2 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -1395,63 +1395,72 @@ void BlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayou
1395 MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); 1395 MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height));
1396} 1396}
1397 1397
1398void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, 1398static Common::Rectangle<f32> NormalizeCrop(Common::Rectangle<int> crop,
1399 const Layout::FramebufferLayout layout) const { 1399 const Tegra::FramebufferConfig& framebuffer) {
1400 const auto& framebuffer_transform_flags = framebuffer.transform_flags; 1400 f32 left, top, right, bottom;
1401 const auto& framebuffer_crop_rect = framebuffer.crop_rect; 1401
1402 1402 if (!crop.IsEmpty()) {
1403 static constexpr Common::Rectangle<f32> texcoords{0.f, 0.f, 1.f, 1.f}; 1403 // If crop rectangle is not empty, apply properties from rectangle.
1404 auto left = texcoords.left; 1404 left = static_cast<f32>(crop.left);
1405 auto right = texcoords.right; 1405 top = static_cast<f32>(crop.top);
1406 1406 right = static_cast<f32>(crop.right);
1407 switch (framebuffer_transform_flags) { 1407 bottom = static_cast<f32>(crop.bottom);
1408 case Service::android::BufferTransformFlags::Unset: 1408 } else {
1409 break; 1409 // Otherwise, fall back to framebuffer dimensions.
1410 case Service::android::BufferTransformFlags::FlipV: 1410 left = 0;
1411 // Flip the framebuffer vertically 1411 top = 0;
1412 left = texcoords.right; 1412 right = static_cast<f32>(framebuffer.width);
1413 right = texcoords.left; 1413 bottom = static_cast<f32>(framebuffer.height);
1414 break;
1415 default:
1416 UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}",
1417 static_cast<u32>(framebuffer_transform_flags));
1418 break;
1419 } 1414 }
1420 1415
1421 UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0); 1416 // Apply transformation flags.
1417 auto framebuffer_transform_flags = framebuffer.transform_flags;
1422 1418
1423 f32 left_start{}; 1419 if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipH)) {
1424 if (framebuffer_crop_rect.Top() > 0) { 1420 // Switch left and right.
1425 left_start = static_cast<f32>(framebuffer_crop_rect.Top()) / 1421 std::swap(left, right);
1426 static_cast<f32>(framebuffer_crop_rect.Bottom());
1427 } 1422 }
1428 f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width); 1423 if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipV)) {
1429 f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height); 1424 // Switch top and bottom.
1430 // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering 1425 std::swap(top, bottom);
1431 // (e.g. handheld mode) on a 1920x1080 framebuffer. 1426 }
1432 if (!fsr) { 1427
1433 if (framebuffer_crop_rect.GetWidth() > 0) { 1428 framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipH;
1434 scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) / 1429 framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipV;
1435 static_cast<f32>(screen_info.width); 1430 if (True(framebuffer_transform_flags)) {
1436 } 1431 UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}",
1437 if (framebuffer_crop_rect.GetHeight() > 0) { 1432 static_cast<u32>(framebuffer_transform_flags));
1438 scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) /
1439 static_cast<f32>(screen_info.height);
1440 }
1441 } 1433 }
1442 1434
1435 return Common::Rectangle<f32>(left, top, right, bottom);
1436}
1437
1438void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
1439 const Layout::FramebufferLayout layout) const {
1440 // Get the normalized crop rectangle.
1441 const auto crop = NormalizeCrop(framebuffer.crop_rect, framebuffer);
1442
1443 // Get the screen properties.
1444 const f32 screen_width = static_cast<f32>(screen_info.width);
1445 const f32 screen_height = static_cast<f32>(screen_info.height);
1446
1447 // Apply the crop.
1448 const f32 left = crop.left / screen_width;
1449 const f32 top = crop.top / screen_height;
1450 const f32 right = crop.right / screen_width;
1451 const f32 bottom = crop.bottom / screen_height;
1452
1453 // Map the coordinates to the screen.
1443 const auto& screen = layout.screen; 1454 const auto& screen = layout.screen;
1444 const auto x = static_cast<f32>(screen.left); 1455 const auto x = static_cast<f32>(screen.left);
1445 const auto y = static_cast<f32>(screen.top); 1456 const auto y = static_cast<f32>(screen.top);
1446 const auto w = static_cast<f32>(screen.GetWidth()); 1457 const auto w = static_cast<f32>(screen.GetWidth());
1447 const auto h = static_cast<f32>(screen.GetHeight()); 1458 const auto h = static_cast<f32>(screen.GetHeight());
1448 data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left_start + left * scale_v); 1459
1449 data.vertices[1] = 1460 data.vertices[0] = ScreenRectVertex(x, y, left, top);
1450 ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left_start + left * scale_v); 1461 data.vertices[1] = ScreenRectVertex(x + w, y, right, top);
1451 data.vertices[2] = 1462 data.vertices[2] = ScreenRectVertex(x, y + h, left, bottom);
1452 ScreenRectVertex(x, y + h, texcoords.top * scale_u, left_start + right * scale_v); 1463 data.vertices[3] = ScreenRectVertex(x + w, y + h, right, bottom);
1453 data.vertices[3] =
1454 ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, left_start + right * scale_v);
1455} 1464}
1456 1465
1457void BlitScreen::CreateSMAA(VkExtent2D smaa_size) { 1466void BlitScreen::CreateSMAA(VkExtent2D smaa_size) {