SDL: Vita: Fixed absence of clipping when viewport is set (1bd51)

From 1bd5110ff00941e0d98e53d29f99832cc0b5b598 Mon Sep 17 00:00:00 2001
From: Wohlstand <[EMAIL REDACTED]>
Date: Sat, 21 Jun 2025 00:28:25 +0300
Subject: [PATCH] Vita: Fixed absence of clipping when viewport is set

#13034

(cherry picked from commit 1c09a7117a94cdc1838a65df8b8e017a09bc5bc1)

# Conflicts:
#	src/render/vitagxm/SDL_render_vita_gxm.c
#	src/render/vitagxm/SDL_render_vita_gxm_types.h
---
 src/render/vitagxm/SDL_render_vita_gxm.c      | 41 +++++++++++++++----
 .../vitagxm/SDL_render_vita_gxm_types.h       |  1 +
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c
index 79dd1163b5008..64653f90a6eeb 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm.c
+++ b/src/render/vitagxm/SDL_render_vita_gxm.c
@@ -862,7 +862,7 @@ static bool SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd
         data->drawstate.cliprect_enabled_dirty = false;
     }
 
-    if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
+    if ((data->drawstate.cliprect_enabled || data->drawstate.viewport_is_set) && data->drawstate.cliprect_dirty) {
         const SDL_Rect *rect = &data->drawstate.cliprect;
         set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
         data->drawstate.cliprect_dirty = false;
@@ -952,20 +952,31 @@ static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer)
 static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
 {
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->internal;
+    int w, h;
+
     StartDrawing(renderer);
 
     data->drawstate.target = renderer->target;
     if (!data->drawstate.target) {
-        int w, h;
         SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
-        if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
-            data->drawstate.viewport_dirty = true; // if the window dimensions changed, invalidate the current viewport, etc.
-            data->drawstate.cliprect_dirty = true;
-            data->drawstate.drawablew = w;
-            data->drawstate.drawableh = h;
+    } else {
+        float fw, fh;
+        if (!SDL_GetTextureSize(renderer->target, &fw, &fh)) {
+            w = data->drawstate.drawablew;
+            h = data->drawstate.drawableh;
+        } else {
+            w = (int)SDL_roundf(fw);
+            h = (int)SDL_roundf(fh);
         }
     }
 
+    if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
+        data->drawstate.viewport_dirty = true; // if the window dimensions changed, invalidate the current viewport, etc.
+        data->drawstate.cliprect_dirty = true;
+        data->drawstate.drawablew = w;
+        data->drawstate.drawableh = h;
+    }
+
     while (cmd) {
         switch (cmd->command) {
 
@@ -976,6 +987,16 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
                 SDL_copyp(viewport, &cmd->data.viewport.rect);
                 data->drawstate.viewport_dirty = true;
                 data->drawstate.cliprect_dirty = true;
+                data->drawstate.viewport_is_set = viewport->x != 0 || viewport->y != 0 || viewport->w != data->drawstate.drawablew || viewport->h != data->drawstate.drawableh;
+                if (!data->drawstate.cliprect_enabled) {
+                    if (data->drawstate.viewport_is_set) {
+                        SDL_copyp(&data->drawstate.cliprect, viewport);
+                        data->drawstate.cliprect.x = 0;
+                        data->drawstate.cliprect.y = 0;
+                    } else {
+                        data->drawstate.cliprect_enabled_dirty = true;
+                    }
+                }
             }
             break;
         }
@@ -983,9 +1004,15 @@ static bool VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *
         case SDL_RENDERCMD_SETCLIPRECT:
         {
             const SDL_Rect *rect = &cmd->data.cliprect.rect;
+            const SDL_Rect *viewport = &data->drawstate.viewport;
             if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
                 data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
                 data->drawstate.cliprect_enabled_dirty = true;
+                if (!data->drawstate.cliprect_enabled && data->drawstate.viewport_is_set) {
+                    SDL_copyp(&data->drawstate.cliprect, viewport);
+                    data->drawstate.cliprect.x = 0;
+                    data->drawstate.cliprect.y = 0;
+                }
             }
 
             if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) {
diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h
index f56814be6eaa5..6fc2c9e81f83d 100644
--- a/src/render/vitagxm/SDL_render_vita_gxm_types.h
+++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h
@@ -105,6 +105,7 @@ typedef struct
 {
     SDL_Rect viewport;
     bool viewport_dirty;
+    bool viewport_is_set;
     SDL_Texture *texture;
     SDL_Texture *target;
     SDL_FColor color;