shithub: choc

Download patch

ref: 7bd39542f9c056acda71d1fb3dd976b08501c468
parent: 3601d9b2393a11dc6819a5cb0e9037e3bc20bd10
author: Simon Howard <fraggle@soulsphere.org>
date: Sun Feb 5 14:39:16 EST 2017

video: Query SDL API for maximum texture size.

Further tweak to #859. Just to be safe, use the SDL renderer API to
determine the maximum texture dimensions of the graphics hardware,
and don't try to create a texture larger than is supported. As an
additional enhancement, print an informational message when we have
limit the intermediate texture size for any reason.

--- a/src/i_video.c
+++ b/src/i_video.c
@@ -538,7 +538,72 @@
     }
 
     currently_grabbed = grab;
+}
 
+static void LimitTextureSize(int *w_upscale, int *h_upscale)
+{
+    SDL_RendererInfo rinfo;
+    int orig_w, orig_h;
+
+    orig_w = *w_upscale;
+    orig_h = *h_upscale;
+
+    // Query renderer and limit to maximum texture dimensions of hardware:
+    if (SDL_GetRendererInfo(renderer, &rinfo) != 0)
+    {
+        I_Error("CreateUpscaledTexture: SDL_GetRendererInfo() call failed: %s",
+                SDL_GetError());
+    }
+
+    while (*w_upscale * SCREENWIDTH > rinfo.max_texture_width)
+    {
+        --*w_upscale;
+    }
+    while (*h_upscale * SCREENHEIGHT > rinfo.max_texture_height)
+    {
+        --*h_upscale;
+    }
+
+    if (*w_upscale < 1 || *h_upscale < 1)
+    {
+        I_Error("CreateUpscaledTexture: Can't create a texture big enough for "
+                "the whole screen! Maximum texture size %dx%d",
+                rinfo.max_texture_width, rinfo.max_texture_height);
+    }
+
+    // We limit the amount of texture memory used for the intermediate buffer.
+    // By default we limit to 1600x1200, which gives pretty good results, but
+    // we allow the user to override this and use more if they want to use
+    // even more (or less, if their graphics card can't handle it).
+
+    if (max_scaling_buffer_pixels < SCREENWIDTH * SCREENHEIGHT)
+    {
+        I_Error("CreateUpscaledTexture: max_scaling_buffer_pixels too small "
+                "to create a texture buffer: %d < %d",
+                max_scaling_buffer_pixels, SCREENWIDTH * SCREENHEIGHT);
+    }
+
+    while (*w_upscale * *h_upscale * SCREENWIDTH * SCREENHEIGHT
+           > max_scaling_buffer_pixels)
+    {
+        if (*w_upscale > *h_upscale)
+        {
+            --*w_upscale;
+        }
+        else
+        {
+            --*h_upscale;
+        }
+    }
+
+    if (*w_upscale != orig_w || *h_upscale != orig_h)
+    {
+        printf("CreateUpscaledTexture: Limited texture size to %dx%d "
+               "(max %d pixels, max texture size %dx%d)\n",
+               *w_upscale * SCREENWIDTH, *h_upscale * SCREENHEIGHT,
+               max_scaling_buffer_pixels,
+               rinfo.max_texture_width, rinfo.max_texture_height);
+    }
 }
 
 static void CreateUpscaledTexture(boolean force)
@@ -591,30 +656,7 @@
         h_upscale = 1;
     }
 
-    // We limit the amount of texture memory used for the intermediate buffer.
-    // By default we limit to 1600x1200, which gives pretty good results, but
-    // we allow the user to override this and use more if they want to use
-    // even more (or less, if their graphics card can't handle it).
-
-    if (max_scaling_buffer_pixels < SCREENWIDTH * SCREENHEIGHT)
-    {
-        I_Error("CreateUpscaledTexture: max_scaling_buffer_pixels too small "
-                "to create a texture buffer: %d < %d",
-                max_scaling_buffer_pixels, SCREENWIDTH * SCREENHEIGHT);
-    }
-
-    while (w_upscale * h_upscale * SCREENWIDTH * SCREENHEIGHT
-           > max_scaling_buffer_pixels)
-    {
-        if (w_upscale > h_upscale)
-        {
-            --w_upscale;
-        }
-        else
-        {
-            --h_upscale;
-        }
-    }
+    LimitTextureSize(&w_upscale, &h_upscale);
 
     // Create a new texture only if the upscale factors have actually changed.