[PATCH 2/6] wined3d: Validate (2D) texture dimensions in texture_init().

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 21 11:40:11 CDT 2016


Instead of for each surface individually.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/surface.c |  24 -----------
 dlls/wined3d/texture.c | 108 +++++++++++++++++++++++++++----------------------
 2 files changed, 59 insertions(+), 73 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 532f6f8..5842d52 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -557,30 +557,6 @@ static HRESULT surface_private_setup(struct wined3d_surface *surface)
         }
     }
 
-    if ((surface->pow2Width > gl_info->limits.texture_size || surface->pow2Height > gl_info->limits.texture_size)
-            && (texture->resource.usage & WINED3DUSAGE_TEXTURE))
-    {
-        /* One of three options:
-         * 1: Do the same as we do with NPOT and scale the texture, (any
-         *    texture ops would require the texture to be scaled which is
-         *    potentially slow)
-         * 2: Set the texture to the maximum size (bad idea).
-         * 3: WARN and return WINED3DERR_NOTAVAILABLE;
-         * 4: Create the surface, but allow it to be used only for DirectDraw
-         *    Blts. Some apps (e.g. Swat 3) create textures with a Height of
-         *    16 and a Width > 3000 and blt 16x16 letter areas from them to
-         *    the render target. */
-        if (texture->resource.pool == WINED3D_POOL_DEFAULT || texture->resource.pool == WINED3D_POOL_MANAGED)
-        {
-            WARN("Unable to allocate a surface which exceeds the maximum OpenGL texture size.\n");
-            return WINED3DERR_NOTAVAILABLE;
-        }
-
-        /* We should never use this surface in combination with OpenGL! */
-        TRACE("Creating an oversized surface: %ux%u.\n",
-                surface->pow2Width, surface->pow2Height);
-    }
-
     if (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
         surface->locations = WINED3D_LOCATION_DISCARDED;
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 4d2a94f..588066f 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -79,7 +79,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
     texture->level_count = level_count;
     texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
     texture->lod = 0;
-    texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
+    texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS;
     if (flags & WINED3D_TEXTURE_CREATE_PIN_SYSMEM)
         texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
 
@@ -1403,39 +1403,59 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         return WINED3DERR_INVALIDCALL;
     }
 
-    /* Non-power2 support. */
-    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
+    pow2_width = desc->width;
+    pow2_height = desc->height;
+    if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)))
+            && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
     {
-        pow2_width = desc->width;
-        pow2_height = desc->height;
-    }
-    else
-    {
-        /* Find the nearest pow2 match. */
-        pow2_width = pow2_height = 1;
-        while (pow2_width < desc->width)
-            pow2_width <<= 1;
-        while (pow2_height < desc->height)
-            pow2_height <<= 1;
-
-        if (pow2_width != desc->width || pow2_height != desc->height)
+        /* level_count == 0 returns an error as well. */
+        if (level_count != 1 || desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
         {
-            /* level_count == 0 returns an error as well */
-            if (level_count != 1 || desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+            if (desc->pool != WINED3D_POOL_SCRATCH)
             {
-                if (desc->pool == WINED3D_POOL_SCRATCH)
-                {
-                    WARN("Creating a scratch mipmapped/cube NPOT texture despite lack of HW support.\n");
-                }
-                else
-                {
-                    WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n");
-                    return WINED3DERR_INVALIDCALL;
-                }
+                WARN("Attempted to create a mipmapped/cube NPOT texture without unconditional NPOT support.\n");
+                return WINED3DERR_INVALIDCALL;
             }
+
+            WARN("Creating a scratch mipmapped/cube NPOT texture despite lack of HW support.\n");
+        }
+        texture->flags |= WINED3D_TEXTURE_COND_NP2;
+
+        if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+        {
+            /* Find the nearest pow2 match. */
+            pow2_width = pow2_height = 1;
+            while (pow2_width < desc->width)
+                pow2_width <<= 1;
+            while (pow2_height < desc->height)
+                pow2_height <<= 1;
+            texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED;
         }
     }
 
+    if ((pow2_width > gl_info->limits.texture_size || pow2_height > gl_info->limits.texture_size)
+            && (desc->usage & WINED3DUSAGE_TEXTURE))
+    {
+        /* One of four options:
+         * 1: Do the same as we do with NPOT and scale the texture. (Any
+         *    texture ops would require the texture to be scaled which is
+         *    potentially slow.)
+         * 2: Set the texture to the maximum size (bad idea).
+         * 3: WARN and return WINED3DERR_NOTAVAILABLE.
+         * 4: Create the surface, but allow it to be used only for DirectDraw
+         *    Blts. Some apps (e.g. Swat 3) create textures with a height of
+         *    16 and a width > 3000 and blt 16x16 letter areas from them to
+         *    the render target. */
+        if (desc->pool == WINED3D_POOL_DEFAULT || desc->pool == WINED3D_POOL_MANAGED)
+        {
+            WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
+            return WINED3DERR_NOTAVAILABLE;
+        }
+
+        /* We should never use this surface in combination with OpenGL. */
+        TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
+    }
+
     /* Calculate levels for mip mapping. */
     if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP)
     {
@@ -1464,40 +1484,30 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
     {
         texture->pow2_matrix[0] = (float)desc->width;
         texture->pow2_matrix[5] = (float)desc->height;
-        texture->pow2_matrix[10] = 1.0f;
-        texture->pow2_matrix[15] = 1.0f;
-        texture->target = GL_TEXTURE_RECTANGLE_ARB;
-        texture->flags |= WINED3D_TEXTURE_COND_NP2;
         texture->flags &= ~(WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS);
+        texture->target = GL_TEXTURE_RECTANGLE_ARB;
     }
     else
     {
-        if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
-            texture->target = GL_TEXTURE_CUBE_MAP_ARB;
-        else
-            texture->target = GL_TEXTURE_2D;
-        if (desc->width == pow2_width && desc->height == pow2_height)
+        if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
         {
-            texture->pow2_matrix[0] = 1.0f;
-            texture->pow2_matrix[5] = 1.0f;
+            texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
+            texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
+            texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
         }
-        else if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
+        else
         {
             texture->pow2_matrix[0] = 1.0f;
             texture->pow2_matrix[5] = 1.0f;
-            texture->flags |= WINED3D_TEXTURE_COND_NP2;
         }
+        if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
+            texture->target = GL_TEXTURE_CUBE_MAP_ARB;
         else
-        {
-            texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
-            texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
-            texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT;
-            texture->flags |= WINED3D_TEXTURE_COND_NP2_EMULATED;
-        }
-        texture->pow2_matrix[10] = 1.0f;
-        texture->pow2_matrix[15] = 1.0f;
+            texture->target = GL_TEXTURE_2D;
     }
-    TRACE("xf(%f) yf(%f)\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
+    texture->pow2_matrix[10] = 1.0f;
+    texture->pow2_matrix[15] = 1.0f;
+    TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
 
     if (!(surfaces = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*surfaces) * level_count * layer_count)))
     {
-- 
2.1.4




More information about the wine-patches mailing list