SDL: METAL: clip rect w/h must be <= render pass

From 3bebdaccb7bff8c40438856081d404a7ce3def30 Mon Sep 17 00:00:00 2001
From: Sylvain Becker <[EMAIL REDACTED]>
Date: Tue, 15 Mar 2022 10:37:17 +0100
Subject: [PATCH] METAL: clip rect w/h must be <= render pass

---
 src/render/metal/SDL_render_metal.m | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 4e51a6d4ea2..329e5b3a01f 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -1255,22 +1255,29 @@ - (void)dealloc
     }
 
     if (statecache->cliprect_dirty) {
-        MTLScissorRect mtlrect;
+        SDL_Rect output;
+        SDL_Rect clip;
         if (statecache->cliprect_enabled) {
-            const SDL_Rect *rect = &statecache->cliprect;
-            mtlrect.x = statecache->viewport.x + rect->x;
-            mtlrect.y = statecache->viewport.y + rect->y;
-            mtlrect.width = rect->w;
-            mtlrect.height = rect->h;
+            clip = statecache->cliprect;
+            clip.x += statecache->viewport.x;
+            clip.y += statecache->viewport.y;
         } else {
-            mtlrect.x = statecache->viewport.x;
-            mtlrect.y = statecache->viewport.y;
-            mtlrect.width = statecache->viewport.w;
-            mtlrect.height = statecache->viewport.h;
+            clip = statecache->viewport;
         }
-        if (mtlrect.width > 0 && mtlrect.height > 0) {
+
+        /* Set Scissor Rect Validation: w/h must be <= render pass */
+        SDL_zero(output);
+        METAL_GetOutputSize(renderer, &output.w, &output.h);
+
+        if (SDL_IntersectRect(&output, &clip, &clip)) {
+            MTLScissorRect mtlrect;
+            mtlrect.x = clip.x;
+            mtlrect.y = clip.y;
+            mtlrect.width = clip.w;
+            mtlrect.height = clip.h;
             [data.mtlcmdencoder setScissorRect:mtlrect];
         }
+
         statecache->cliprect_dirty = SDL_FALSE;
     }