[7/9] wined3d: Add support for native NPOT textures

H. Verbeet hverbeet at gmail.com
Tue Sep 26 13:31:48 CDT 2006


Most relatively modern cards support non-power-of-two textures, make
use of this when available. This patch also fixes applications that
use NPOT textures in combination with shaders, since the other modes
can't work with shaders (and pretty much anything that supports
shaders also supports NPOT textures).

Changelog:
  -  Add support for native NPOT textures
-------------- next part --------------
---

 dlls/wined3d/device.c          |   31 ++++++++++++++++++++-----------
 dlls/wined3d/directx.c         |    9 +++++++++
 dlls/wined3d/wined3d_main.c    |    2 +-
 dlls/wined3d/wined3d_private.h |    1 +
 include/wine/wined3d_gl.h      |    1 +
 5 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 58047e0..6b7ecfa 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -971,11 +971,15 @@ static HRESULT  WINAPI IWineD3DDeviceImp
       *******************************/
 
     /* Non-power2 support */
-
-    /* Find the nearest pow2 match */
-    pow2Width = pow2Height = 1;
-    while (pow2Width < Width) pow2Width <<= 1;
-    while (pow2Height < Height) pow2Height <<= 1;
+    if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
+        pow2Width = Width;
+        pow2Height = Height;
+    } else {
+        /* Find the nearest pow2 match */
+        pow2Width = pow2Height = 1;
+        while (pow2Width < Width) pow2Width <<= 1;
+        while (pow2Height < Height) pow2Height <<= 1;
+    }
 
     if (pow2Width > Width || pow2Height > Height) {
          /** TODO: add support for non power two compressed textures (OpenGL 2 provices support for * non-power-two textures gratis) **/
@@ -1125,8 +1129,8 @@ static HRESULT  WINAPI IWineD3DDeviceImp
     UINT tmpW;
     UINT tmpH;
     HRESULT hr;
-    unsigned int pow2Width  = Width;
-    unsigned int pow2Height = Height;
+    unsigned int pow2Width;
+    unsigned int pow2Height;
 
 
     TRACE("(%p) : Width %d, Height %d, Levels %d, Usage %#lx\n", This, Width, Height, Levels, Usage);
@@ -1146,10 +1150,15 @@ static HRESULT  WINAPI IWineD3DDeviceImp
     object->height = Height;
 
     /** Non-power2 support **/
-    /* Find the nearest pow2 match */
-    pow2Width = pow2Height = 1;
-    while (pow2Width < Width) pow2Width <<= 1;
-    while (pow2Height < Height) pow2Height <<= 1;
+    if (wined3d_settings.nonpower2_mode == NP2_NATIVE) {
+        pow2Width = Width;
+        pow2Height = Height;
+    } else {
+        /* Find the nearest pow2 match */
+        pow2Width = pow2Height = 1;
+        while (pow2Width < Width) pow2Width <<= 1;
+        while (pow2Height < Height) pow2Height <<= 1;
+    }
 
     /** FIXME: add support for real non-power-two if it's provided by the video card **/
     /* Precalculated scaling for 'faked' non power of two texture coords */
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3a2bc7e..68914d6 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -590,6 +590,9 @@ #undef USE_GL_FUNC
             } else if (strcmp(ThisExtn, "GL_ARB_texture_mirrored_repeat") == 0) {
                 TRACE_(d3d_caps)(" FOUND: ARB Texture mirrored repeat support\n");
                 gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] = TRUE;
+            } else if (strcmp(ThisExtn, "GL_ARB_texture_non_power_of_two") == 0) {
+                TRACE_(d3d_caps)(" FOUND: ARB NPOT texture support\n");
+                gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = TRUE;
             } else if (strcmp(ThisExtn, "GLX_ARB_multisample") == 0) {
                 TRACE_(d3d_caps)(" FOUND: ARB multisample support\n");
                 gl_info->supported[ARB_MULTISAMPLE] = TRUE;
@@ -765,6 +768,12 @@ #undef USE_GL_FUNC
 
     gl_info->max_sampler_stages = max(gl_info->max_samplers, gl_info->max_texture_stages);
 
+    /* We can only use NP2_NATIVE when the hardware supports it. */
+    if (wined3d_settings.nonpower2_mode == NP2_NATIVE && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) {
+        WARN_(d3d_caps)("GL_ARB_texture_non_power_of_two not supported, falling back to NP2_NONE NPOT mode.\n");
+        wined3d_settings.nonpower2_mode = NP2_NONE;
+    }
+
     /* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
      * features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
      * in case of the latest videocards in the number of pixel/vertex pipelines.
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index af4e5f3..ab6fb3d 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -42,7 +42,7 @@ wined3d_settings_t wined3d_settings = 
     FALSE,          /* Use of GLSL disabled by default */
     SHADER_ARB,     /* Use ARB vertex programs, when available */
     SHADER_ARB,     /* Use ARB fragment programs, when available */
-    NP2_NONE,       /* Box NPOT textures */
+    NP2_NATIVE,     /* Use native NPOT textures, when available */
     RTL_AUTO,       /* Automatically determine best locking method */
     64*1024*1024    /* 64MB texture memory by default */
 };
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index da607de..ff84c5b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -132,6 +132,7 @@ #define VBO_HW     1
 
 #define NP2_NONE   0
 #define NP2_REPACK 1
+#define NP2_NATIVE 2
 
 #define SHADER_SW   0
 #define SHADER_ARB  1
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h
index 1832287..1cc6409 100644
--- a/include/wine/wined3d_gl.h
+++ b/include/wine/wined3d_gl.h
@@ -1424,6 +1424,7 @@ typedef enum _GL_SupportedExt {
   ARB_HALF_FLOAT_PIXEL,
   ARB_TEXTURE_BORDER_CLAMP,
   ARB_TEXTURE_MIRRORED_REPEAT,
+  ARB_TEXTURE_NON_POWER_OF_TWO,
   ARB_VERTEX_PROGRAM,
   ARB_VERTEX_BLEND,
   ARB_VERTEX_BUFFER_OBJECT,


More information about the wine-patches mailing list