diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 130 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_fsr.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_fsr.h | 2 |
3 files changed, 86 insertions, 70 deletions
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 459ab32c2..66483a900 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -137,6 +137,56 @@ BlitScreen::BlitScreen(Core::Memory::Memory& cpu_memory_, Core::Frontend::EmuWin | |||
| 137 | 137 | ||
| 138 | BlitScreen::~BlitScreen() = default; | 138 | BlitScreen::~BlitScreen() = default; |
| 139 | 139 | ||
| 140 | static Common::Rectangle<f32> NormalizeCrop(const Tegra::FramebufferConfig& framebuffer, | ||
| 141 | const ScreenInfo& screen_info) { | ||
| 142 | f32 left, top, right, bottom; | ||
| 143 | |||
| 144 | if (!framebuffer.crop_rect.IsEmpty()) { | ||
| 145 | // If crop rectangle is not empty, apply properties from rectangle. | ||
| 146 | left = static_cast<f32>(framebuffer.crop_rect.left); | ||
| 147 | top = static_cast<f32>(framebuffer.crop_rect.top); | ||
| 148 | right = static_cast<f32>(framebuffer.crop_rect.right); | ||
| 149 | bottom = static_cast<f32>(framebuffer.crop_rect.bottom); | ||
| 150 | } else { | ||
| 151 | // Otherwise, fall back to framebuffer dimensions. | ||
| 152 | left = 0; | ||
| 153 | top = 0; | ||
| 154 | right = static_cast<f32>(framebuffer.width); | ||
| 155 | bottom = static_cast<f32>(framebuffer.height); | ||
| 156 | } | ||
| 157 | |||
| 158 | // Apply transformation flags. | ||
| 159 | auto framebuffer_transform_flags = framebuffer.transform_flags; | ||
| 160 | |||
| 161 | if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipH)) { | ||
| 162 | // Switch left and right. | ||
| 163 | std::swap(left, right); | ||
| 164 | } | ||
| 165 | if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipV)) { | ||
| 166 | // Switch top and bottom. | ||
| 167 | std::swap(top, bottom); | ||
| 168 | } | ||
| 169 | |||
| 170 | framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipH; | ||
| 171 | framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipV; | ||
| 172 | if (True(framebuffer_transform_flags)) { | ||
| 173 | UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}", | ||
| 174 | static_cast<u32>(framebuffer_transform_flags)); | ||
| 175 | } | ||
| 176 | |||
| 177 | // Get the screen properties. | ||
| 178 | const f32 screen_width = static_cast<f32>(screen_info.width); | ||
| 179 | const f32 screen_height = static_cast<f32>(screen_info.height); | ||
| 180 | |||
| 181 | // Normalize coordinate space. | ||
| 182 | left /= screen_width; | ||
| 183 | top /= screen_height; | ||
| 184 | right /= screen_width; | ||
| 185 | bottom /= screen_height; | ||
| 186 | |||
| 187 | return Common::Rectangle<f32>(left, top, right, bottom); | ||
| 188 | } | ||
| 189 | |||
| 140 | void BlitScreen::Recreate() { | 190 | void BlitScreen::Recreate() { |
| 141 | present_manager.WaitPresent(); | 191 | present_manager.WaitPresent(); |
| 142 | scheduler.Finish(); | 192 | scheduler.Finish(); |
| @@ -354,17 +404,10 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, | |||
| 354 | source_image_view = smaa->Draw(scheduler, image_index, source_image, source_image_view); | 404 | source_image_view = smaa->Draw(scheduler, image_index, source_image, source_image_view); |
| 355 | } | 405 | } |
| 356 | if (fsr) { | 406 | if (fsr) { |
| 357 | auto crop_rect = framebuffer.crop_rect; | 407 | const auto crop_rect = NormalizeCrop(framebuffer, screen_info); |
| 358 | if (crop_rect.GetWidth() == 0) { | 408 | const VkExtent2D fsr_input_size{ |
| 359 | crop_rect.right = framebuffer.width; | 409 | .width = Settings::values.resolution_info.ScaleUp(screen_info.width), |
| 360 | } | 410 | .height = Settings::values.resolution_info.ScaleUp(screen_info.height), |
| 361 | if (crop_rect.GetHeight() == 0) { | ||
| 362 | crop_rect.bottom = framebuffer.height; | ||
| 363 | } | ||
| 364 | crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor); | ||
| 365 | VkExtent2D fsr_input_size{ | ||
| 366 | .width = Settings::values.resolution_info.ScaleUp(framebuffer.width), | ||
| 367 | .height = Settings::values.resolution_info.ScaleUp(framebuffer.height), | ||
| 368 | }; | 411 | }; |
| 369 | VkImageView fsr_image_view = | 412 | VkImageView fsr_image_view = |
| 370 | fsr->Draw(scheduler, image_index, source_image_view, fsr_input_size, crop_rect); | 413 | fsr->Draw(scheduler, image_index, source_image_view, fsr_input_size, crop_rect); |
| @@ -1395,61 +1438,28 @@ void BlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayou | |||
| 1395 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); | 1438 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); |
| 1396 | } | 1439 | } |
| 1397 | 1440 | ||
| 1398 | static Common::Rectangle<f32> NormalizeCrop(Common::Rectangle<int> crop, | 1441 | void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, |
| 1399 | const Tegra::FramebufferConfig& framebuffer) { | 1442 | const Layout::FramebufferLayout layout) const { |
| 1400 | f32 left, top, right, bottom; | 1443 | f32 left, top, right, bottom; |
| 1401 | 1444 | ||
| 1402 | if (!crop.IsEmpty()) { | 1445 | if (fsr) { |
| 1403 | // If crop rectangle is not empty, apply properties from rectangle. | 1446 | // FSR has already applied the crop, so we just want to render the image |
| 1404 | left = static_cast<f32>(crop.left); | 1447 | // it has produced. |
| 1405 | top = static_cast<f32>(crop.top); | ||
| 1406 | right = static_cast<f32>(crop.right); | ||
| 1407 | bottom = static_cast<f32>(crop.bottom); | ||
| 1408 | } else { | ||
| 1409 | // Otherwise, fall back to framebuffer dimensions. | ||
| 1410 | left = 0; | 1448 | left = 0; |
| 1411 | top = 0; | 1449 | top = 0; |
| 1412 | right = static_cast<f32>(framebuffer.width); | 1450 | right = 1; |
| 1413 | bottom = static_cast<f32>(framebuffer.height); | 1451 | bottom = 1; |
| 1414 | } | 1452 | } else { |
| 1415 | 1453 | // Get the normalized crop rectangle. | |
| 1416 | // Apply transformation flags. | 1454 | const auto crop = NormalizeCrop(framebuffer, screen_info); |
| 1417 | auto framebuffer_transform_flags = framebuffer.transform_flags; | 1455 | |
| 1418 | 1456 | // Apply the crop. | |
| 1419 | if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipH)) { | 1457 | left = crop.left; |
| 1420 | // Switch left and right. | 1458 | top = crop.top; |
| 1421 | std::swap(left, right); | 1459 | right = crop.right; |
| 1422 | } | 1460 | bottom = crop.bottom; |
| 1423 | if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipV)) { | ||
| 1424 | // Switch top and bottom. | ||
| 1425 | std::swap(top, bottom); | ||
| 1426 | } | ||
| 1427 | |||
| 1428 | framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipH; | ||
| 1429 | framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipV; | ||
| 1430 | if (True(framebuffer_transform_flags)) { | ||
| 1431 | UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}", | ||
| 1432 | static_cast<u32>(framebuffer_transform_flags)); | ||
| 1433 | } | 1461 | } |
| 1434 | 1462 | ||
| 1435 | return Common::Rectangle<f32>(left, top, right, bottom); | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | void 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. | 1463 | // Map the coordinates to the screen. |
| 1454 | const auto& screen = layout.screen; | 1464 | const auto& screen = layout.screen; |
| 1455 | const auto x = static_cast<f32>(screen.left); | 1465 | const auto x = static_cast<f32>(screen.left); |
diff --git a/src/video_core/renderer_vulkan/vk_fsr.cpp b/src/video_core/renderer_vulkan/vk_fsr.cpp index ce8f3f3c2..f7a05fbc0 100644 --- a/src/video_core/renderer_vulkan/vk_fsr.cpp +++ b/src/video_core/renderer_vulkan/vk_fsr.cpp | |||
| @@ -34,7 +34,7 @@ FSR::FSR(const Device& device_, MemoryAllocator& memory_allocator_, size_t image | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, | 36 | VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, |
| 37 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect) { | 37 | VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect) { |
| 38 | 38 | ||
| 39 | UpdateDescriptorSet(image_index, image_view); | 39 | UpdateDescriptorSet(image_index, image_view); |
| 40 | 40 | ||
| @@ -61,15 +61,21 @@ VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImageView imag | |||
| 61 | 61 | ||
| 62 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *easu_pipeline); | 62 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *easu_pipeline); |
| 63 | 63 | ||
| 64 | const f32 input_image_width = static_cast<f32>(input_image_extent.width); | ||
| 65 | const f32 input_image_height = static_cast<f32>(input_image_extent.height); | ||
| 66 | const f32 output_image_width = static_cast<f32>(output_size.width); | ||
| 67 | const f32 output_image_height = static_cast<f32>(output_size.height); | ||
| 68 | const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_image_width; | ||
| 69 | const f32 viewport_x = crop_rect.left * input_image_width; | ||
| 70 | const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_image_height; | ||
| 71 | const f32 viewport_y = crop_rect.top * input_image_height; | ||
| 72 | |||
| 64 | std::array<u32, 4 * 4> push_constants; | 73 | std::array<u32, 4 * 4> push_constants; |
| 65 | FsrEasuConOffset( | 74 | FsrEasuConOffset(push_constants.data() + 0, push_constants.data() + 4, |
| 66 | push_constants.data() + 0, push_constants.data() + 4, push_constants.data() + 8, | 75 | push_constants.data() + 8, push_constants.data() + 12, |
| 67 | push_constants.data() + 12, | 76 | |
| 68 | 77 | viewport_width, viewport_height, input_image_width, input_image_height, | |
| 69 | static_cast<f32>(crop_rect.GetWidth()), static_cast<f32>(crop_rect.GetHeight()), | 78 | output_image_width, output_image_height, viewport_x, viewport_y); |
| 70 | static_cast<f32>(input_image_extent.width), static_cast<f32>(input_image_extent.height), | ||
| 71 | static_cast<f32>(output_size.width), static_cast<f32>(output_size.height), | ||
| 72 | static_cast<f32>(crop_rect.left), static_cast<f32>(crop_rect.top)); | ||
| 73 | cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, push_constants); | 79 | cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, push_constants); |
| 74 | 80 | ||
| 75 | { | 81 | { |
diff --git a/src/video_core/renderer_vulkan/vk_fsr.h b/src/video_core/renderer_vulkan/vk_fsr.h index 8bb9fc23a..3505c1416 100644 --- a/src/video_core/renderer_vulkan/vk_fsr.h +++ b/src/video_core/renderer_vulkan/vk_fsr.h | |||
| @@ -17,7 +17,7 @@ public: | |||
| 17 | explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, | 17 | explicit FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count, |
| 18 | VkExtent2D output_size); | 18 | VkExtent2D output_size); |
| 19 | VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, | 19 | VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImageView image_view, |
| 20 | VkExtent2D input_image_extent, const Common::Rectangle<int>& crop_rect); | 20 | VkExtent2D input_image_extent, const Common::Rectangle<f32>& crop_rect); |
| 21 | 21 | ||
| 22 | private: | 22 | private: |
| 23 | void CreateDescriptorPool(); | 23 | void CreateDescriptorPool(); |