aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/engines/fermi_2d.cpp
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-09-27 16:10:45 -0400
committerFernandoS27 <fsahmkow27@gmail.com>2019-10-17 10:38:44 -0400
commitea7b91dbf9796a40dae97888d9e9489d9eecf495 (patch)
treef18e40e15f11c164ee136ac0574700c2257d6ada /src/video_core/engines/fermi_2d.cpp
parent9f3e82bb7bb42eea87ef557ac07acc409cc5d60b (diff)
Fermi2D: limit blit area to only available area
Normaly OpenGL does not care if the areas exceed the texture regions but other backends such as Vulkan do care about the limits of this areas. This PR crops the areas of the blit in order that they don't surpass the limits of the textures. This should help Vulkan and faulty OpenGL drivers
Diffstat (limited to 'src/video_core/engines/fermi_2d.cpp')
-rw-r--r--src/video_core/engines/fermi_2d.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp
index 7ff44f06d2..c2d4dcc09b 100644
--- a/src/video_core/engines/fermi_2d.cpp
+++ b/src/video_core/engines/fermi_2d.cpp
@@ -47,10 +47,20 @@ void Fermi2D::HandleSurfaceCopy() {
src_blit_x2 = static_cast<u32>((regs.blit_src_x >> 32) + regs.blit_dst_width);
src_blit_y2 = static_cast<u32>((regs.blit_src_y >> 32) + regs.blit_dst_height);
}
- const Common::Rectangle<u32> src_rect{src_blit_x1, src_blit_y1, src_blit_x2, src_blit_y2};
- const Common::Rectangle<u32> dst_rect{regs.blit_dst_x, regs.blit_dst_y,
- regs.blit_dst_x + regs.blit_dst_width,
- regs.blit_dst_y + regs.blit_dst_height};
+ const u32 dst_blit_x2 = regs.blit_dst_x + regs.blit_dst_width;
+ const u32 dst_blit_y2 = regs.blit_dst_x + regs.blit_dst_height;
+ const u32 excess_src_x2 = std::max<s32>(0, dst_blit_x2 - regs.dst.width);
+ const u32 excess_src_y2 = std::max<s32>(0, dst_blit_y2 - regs.dst.height);
+ const u32 excess_dst_x2 = std::max<s32>(0, src_blit_x2 - regs.src.width);
+ const u32 excess_dst_y2 = std::max<s32>(0, src_blit_y2 - regs.src.height);
+
+ const Common::Rectangle<u32> src_rect{
+ src_blit_x1, src_blit_y1, std::min<u32>(regs.src.width, src_blit_x2) - excess_src_x2,
+ std::min<u32>(regs.src.height, src_blit_y2) - excess_src_y2};
+ const Common::Rectangle<u32> dst_rect{
+ regs.blit_dst_x, regs.blit_dst_y,
+ std::min<u32>(regs.dst.width, dst_blit_x2) - excess_dst_x2,
+ std::min<u32>(regs.dst.height, dst_blit_y2) - excess_dst_y2};
Config copy_config;
copy_config.operation = regs.operation;
copy_config.filter = regs.blit_control.filter;