[PATCH] WineD3D: Use GL_ARB_texture_non_power_of_two emulation=0A=

Stefan Doesinger stefan at codeweavers.com
Tue Jul 8 18:59:10 CDT 2008


=0A=
ATI cards prior to the radeon HD series did not have=0A=
unconditional non power of two support. So far we've used=0A=
texture_rectangle for that, or created a bigger power of two=0A=
texture with padding. This had the disadvantage that we had to=0A=
correct the coordinates, which causes extreme problems with=0A=
shaders(doesn't work, pretty much).=0A=
=0A=
Both the MacOS and the fglrx driver have support for=0A=
GL_ARB_texture_non_power_of_two, and run it on the hardware as=0A=
long as we stay within the texture_rectangle limitations. This=0A=
allows us to have conditional non power of two textures with=0A=
normalized coordinates. This patch adds an internal extension,=0A=
and the code creates a regular GL_TEXTURE_2D texture with NP2=0A=
size, but refuses mipmapping, filtering and texture_rectangle=0A=
incompatible operations. This makes np2 textures work with=0A=
shaders on fglrx and macos.=0A=
---=0A=
 dlls/wined3d/basetexture.c       |   58 =
+++++++++++++++++++++++++------------=0A=
 dlls/wined3d/cubetexture.c       |    8 +++++=0A=
 dlls/wined3d/device.c            |   16 +++++++++-=0A=
 dlls/wined3d/directx.c           |   39 +++++++++++++++----------=0A=
 dlls/wined3d/state.c             |    8 +++++=0A=
 dlls/wined3d/surface.c           |    2 +-=0A=
 dlls/wined3d/texture.c           |    8 +++++=0A=
 dlls/wined3d/volumetexture.c     |    8 +++++=0A=
 dlls/wined3d/wined3d_private.h   |    1 +=0A=
 include/wine/wined3d_gl.h        |    3 ++=0A=
 include/wine/wined3d_interface.h |    8 +++++=0A=
 11 files changed, 121 insertions(+), 38 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c=0A=
index ace6124..863ffbd 100644=0A=
--- a/dlls/wined3d/basetexture.c=0A=
+++ b/dlls/wined3d/basetexture.c=0A=
@@ -304,7 +304,9 @@ HRESULT WINAPI =
IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {=0A=
             /* For a new texture we have to set the textures levels =
after binding the texture.=0A=
              * In theory this is all we should ever have to do, but =
because ATI's drivers are broken, we=0A=
              * also need to set the texture dimensions before the =
texture is set=0A=
-             * Beware that texture rectangles do not support mipmapping.=0A=
+             * Beware that texture rectangles do not support =
mipmapping, but set the maxmiplevel if we're=0A=
+             * relying on the partial GL_ARB_texture_non_power_of_two =
emulation with texture rectangles=0A=
+             * (ie, do not care for cond_np2 here, just look for =
GL_TEXTURE_RECTANGLE_ARB)=0A=
              */=0A=
             if(textureDimensions !=3D GL_TEXTURE_RECTANGLE_ARB) {=0A=
                 TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", =
This->baseTexture.levels - 1);=0A=
@@ -354,6 +356,12 @@ UINT WINAPI =
IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *if=0A=
     return WINED3D_OK;=0A=
 }=0A=
 =0A=
+BOOL WINAPI IWineD3DBaseTextureImpl_IsCondNP2(IWineD3DBaseTexture =
*iface){=0A=
+    IWineD3DBaseTextureImpl *This =3D (IWineD3DBaseTextureImpl *)iface;=0A=
+    FIXME("(%p) : This shouldn't be called\n", This);=0A=
+    return FALSE;=0A=
+}=0A=
+=0A=
 static inline GLenum warpLookupType(WINED3DSAMPLERSTATETYPE Type) {=0A=
     switch(Type) {=0A=
     case WINED3DSAMP_ADDRESSU:=0A=
@@ -368,7 +376,8 @@ static inline GLenum =
warpLookupType(WINED3DSAMPLERSTATETYPE Type) {=0A=
     }=0A=
 }=0A=
 =0A=
-static inline void apply_wrap(const GLint textureDimensions, const =
DWORD state, const GLint type) {=0A=
+static inline void apply_wrap(const GLint textureDimensions, const =
DWORD state, const GLint type,=0A=
+                              BOOL cond_np2) {=0A=
     GLint wrapParm;=0A=
 =0A=
     if (state < minLookup[WINELOOKUP_WARPPARAM] || state > =
maxLookup[WINELOOKUP_WARPPARAM]) {=0A=
@@ -377,7 +386,7 @@ static inline void apply_wrap(const GLint =
textureDimensions, const DWORD state,=0A=
         if(textureDimensions=3D=3DGL_TEXTURE_CUBE_MAP_ARB) {=0A=
             /* Cubemaps are always set to clamp, regardless of the =
sampler state. */=0A=
             wrapParm =3D GL_CLAMP_TO_EDGE;=0A=
-        } else if(textureDimensions=3D=3DGL_TEXTURE_RECTANGLE_ARB) {=0A=
+        } else if(cond_np2) {=0A=
             if(state =3D=3D WINED3DTADDRESS_WRAP) {=0A=
                 wrapParm =3D GL_CLAMP_TO_EDGE;=0A=
             } else {=0A=
@@ -398,24 +407,25 @@ void WINAPI =
IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface=0A=
     IWineD3DBaseTextureImpl *This =3D (IWineD3DBaseTextureImpl *)iface;=0A=
     DWORD state;=0A=
     GLint textureDimensions =3D =
IWineD3DBaseTexture_GetTextureDimensions(iface);=0A=
+    BOOL cond_np2 =3D IWineD3DBaseTexture_IsCondNP2(iface);=0A=
 =0A=
     IWineD3DBaseTexture_PreLoad(iface);=0A=
 =0A=
     if(samplerStates[WINED3DSAMP_ADDRESSU]      !=3D =
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]) {=0A=
         state =3D samplerStates[WINED3DSAMP_ADDRESSU];=0A=
-        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S);=0A=
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S, =
cond_np2);=0A=
         This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] =3D state;=0A=
     }=0A=
 =0A=
     if(samplerStates[WINED3DSAMP_ADDRESSV]      !=3D =
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]) {=0A=
         state =3D samplerStates[WINED3DSAMP_ADDRESSV];=0A=
-        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T);=0A=
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T, =
cond_np2);=0A=
         This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] =3D state;=0A=
     }=0A=
 =0A=
     if(samplerStates[WINED3DSAMP_ADDRESSW]      !=3D =
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]) {=0A=
         state =3D samplerStates[WINED3DSAMP_ADDRESSW];=0A=
-        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R);=0A=
+        apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R, =
cond_np2);=0A=
         This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] =3D state;=0A=
     }=0A=
 =0A=
@@ -441,22 +451,29 @@ void WINAPI =
IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface=0A=
             glTexParameteri(textureDimensions, GL_TEXTURE_MAG_FILTER, =
glValue);=0A=
             /* We need to reset the Anisotropic filtering state when we =
change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit =
weird, check the documentation to see how it should be switched off. */=0A=
             if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && =
WINED3DTEXF_ANISOTROPIC =3D=3D state &&=0A=
-                textureDimensions !=3D GL_TEXTURE_RECTANGLE_ARB) {=0A=
+                !cond_np2) {=0A=
                 glTexParameteri(textureDimensions, =
GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);=0A=
             }=0A=
             This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] =3D state;=0A=
         }=0A=
     }=0A=
 =0A=
-    if(textureDimensions !=3D GL_TEXTURE_RECTANGLE_ARB &&=0A=
-       (samplerStates[WINED3DSAMP_MINFILTER]     !=3D =
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] ||=0A=
+    if((samplerStates[WINED3DSAMP_MINFILTER]     !=3D =
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] ||=0A=
         samplerStates[WINED3DSAMP_MIPFILTER]     !=3D =
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] ||=0A=
         samplerStates[WINED3DSAMP_MAXMIPLEVEL]   !=3D =
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL])) {=0A=
         GLint glValue;=0A=
+        DWORD mipfilter, minfilter;=0A=
 =0A=
         This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] =3D =
samplerStates[WINED3DSAMP_MIPFILTER];=0A=
         This->baseTexture.states[WINED3DTEXSTA_MINFILTER] =3D =
samplerStates[WINED3DSAMP_MINFILTER];=0A=
         This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] =3D =
samplerStates[WINED3DSAMP_MAXMIPLEVEL];=0A=
+        if(cond_np2) {=0A=
+            mipfilter =3D WINED3DTEXF_NONE;=0A=
+            minfilter =3D WINED3DTEXF_POINT;=0A=
+        } else {=0A=
+            mipfilter =3D samplerStates[WINED3DSAMP_MIPFILTER];=0A=
+            minfilter =3D samplerStates[WINED3DSAMP_MINFILTER];=0A=
+        }=0A=
 =0A=
         if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > =
WINED3DTEXF_ANISOTROPIC ||=0A=
             This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > =
WINED3DTEXF_LINEAR)=0A=
@@ -467,8 +484,8 @@ void WINAPI =
IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface=0A=
                   This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]);=0A=
         }=0A=
         glValue =3D (*This->baseTexture.minMipLookup)=0A=
-                =
[min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), =
WINED3DTEXF_ANISOTROPIC)]=0A=
-                =
[min(max(samplerStates[WINED3DSAMP_MIPFILTER],WINED3DTEXF_NONE), =
WINED3DTEXF_LINEAR)];=0A=
+                [min(max(minfilter,WINED3DTEXF_NONE), =
WINED3DTEXF_ANISOTROPIC)]=0A=
+                [min(max(mipfilter,WINED3DTEXF_NONE), =
WINED3DTEXF_LINEAR)];=0A=
 =0A=
         TRACE("ValueMIN=3D%d, ValueMIP=3D%d, setting MINFILTER to %x\n",=0A=
               samplerStates[WINED3DSAMP_MINFILTER],=0A=
@@ -476,18 +493,20 @@ void WINAPI =
IWineD3DBaseTextureImpl_ApplyStateChanges(IWineD3DBaseTexture *iface=0A=
         glTexParameteri(textureDimensions, GL_TEXTURE_MIN_FILTER, =
glValue);=0A=
         checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");=0A=
 =0A=
-        if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] =3D=3D =
WINED3DTEXF_NONE) {=0A=
-            glValue =3D 0;=0A=
-        } else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] =
>=3D This->baseTexture.levels) {=0A=
-            glValue =3D This->baseTexture.levels - 1;=0A=
-        } else {=0A=
-            glValue =3D =
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];=0A=
+        if(!cond_np2) {=0A=
+            if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] =3D=3D =
WINED3DTEXF_NONE) {=0A=
+                glValue =3D 0;=0A=
+            } else =
if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >=3D =
This->baseTexture.levels) {=0A=
+                glValue =3D This->baseTexture.levels - 1;=0A=
+            } else {=0A=
+                glValue =3D =
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL];=0A=
+            }=0A=
+            glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, =
glValue);=0A=
         }=0A=
-        glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, =
glValue);=0A=
     }=0A=
 =0A=
     if(samplerStates[WINED3DSAMP_MAXANISOTROPY] !=3D =
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) {=0A=
-        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && =
textureDimensions !=3D GL_TEXTURE_RECTANGLE_ARB) {=0A=
+        if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && !cond_np2) {=0A=
             glTexParameteri(textureDimensions, =
GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);=0A=
             checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT =
...");=0A=
         } else {=0A=
@@ -528,6 +547,7 @@ static const IWineD3DBaseTextureVtbl =
IWineD3DBaseTexture_Vtbl =3D=0A=
     IWineD3DBaseTextureImpl_BindTexture,=0A=
     IWineD3DBaseTextureImpl_UnBindTexture,=0A=
     IWineD3DBaseTextureImpl_GetTextureDimensions,=0A=
+    IWineD3DBaseTextureImpl_IsCondNP2,=0A=
     IWineD3DBaseTextureImpl_ApplyStateChanges=0A=
 =0A=
 };=0A=
diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c=0A=
index 175a2cd..39026df 100644=0A=
--- a/dlls/wined3d/cubetexture.c=0A=
+++ b/dlls/wined3d/cubetexture.c=0A=
@@ -267,6 +267,13 @@ static UINT WINAPI =
IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeText=0A=
     return GL_TEXTURE_CUBE_MAP_ARB;=0A=
 }=0A=
 =0A=
+static BOOL WINAPI =
IWineD3DCubeTextureImpl_IsCondNP2(IWineD3DCubeTexture *iface) {=0A=
+    IWineD3DCubeTextureImpl *This =3D (IWineD3DCubeTextureImpl *)iface;=0A=
+    TRACE("(%p)\n", This);=0A=
+=0A=
+    return FALSE;=0A=
+}=0A=
+=0A=
 static void WINAPI =
IWineD3DCubeTextureImpl_ApplyStateChanges(IWineD3DCubeTexture *iface, =0A=
                                                         const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], =0A=
                                                         const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {=0A=
@@ -404,6 +411,7 @@ const IWineD3DCubeTextureVtbl =
IWineD3DCubeTexture_Vtbl =3D=0A=
     IWineD3DCubeTextureImpl_BindTexture,=0A=
     IWineD3DCubeTextureImpl_UnBindTexture,=0A=
     IWineD3DCubeTextureImpl_GetTextureDimensions,=0A=
+    IWineD3DCubeTextureImpl_IsCondNP2,=0A=
     IWineD3DCubeTextureImpl_ApplyStateChanges,=0A=
     /* IWineD3DCubeTexture */=0A=
     IWineD3DCubeTextureImpl_Destroy,=0A=
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c=0A=
index 0e7c21a..e6a1112 100644=0A=
--- a/dlls/wined3d/device.c=0A=
+++ b/dlls/wined3d/device.c=0A=
@@ -818,7 +818,16 @@ static HRESULT  WINAPI =
IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U=0A=
        is used in combination with texture uploads =
(RTL_READTEX/RTL_TEXTEX). The reason is that EXT_PALETTED_TEXTURE=0A=
        doesn't work in combination with ARB_TEXTURE_RECTANGLE.=0A=
     */=0A=
-    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE) &&=0A=
+    if(GL_SUPPORT(WINE_NORMALIZED_TEXRECT) && (Width !=3D pow2Width || =
Height !=3D pow2Height)) {=0A=
+        object->baseTexture.pow2Matrix[0] =3D  1.0;=0A=
+        object->baseTexture.pow2Matrix[5] =3D  1.0;=0A=
+        object->baseTexture.pow2Matrix[10] =3D 1.0;=0A=
+        object->baseTexture.pow2Matrix[15] =3D 1.0;=0A=
+        object->target =3D GL_TEXTURE_2D;=0A=
+        object->cond_np2 =3D TRUE;=0A=
+        pow2Width =3D Width;=0A=
+        pow2Height =3D Height;=0A=
+    } else if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE) &&=0A=
        (Width !=3D pow2Width || Height !=3D pow2Height) &&=0A=
        !((Format =3D=3D WINED3DFMT_P8) && =
GL_SUPPORT(EXT_PALETTED_TEXTURE) && =
(wined3d_settings.rendertargetlock_mode =3D=3D RTL_READTEX || =
wined3d_settings.rendertargetlock_mode =3D=3D RTL_TEXTEX)))=0A=
     {=0A=
@@ -827,12 +836,14 @@ static HRESULT  WINAPI =
IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, U=0A=
         object->baseTexture.pow2Matrix[10] =3D 1.0;=0A=
         object->baseTexture.pow2Matrix[15] =3D 1.0;=0A=
         object->target =3D GL_TEXTURE_RECTANGLE_ARB;=0A=
+        object->cond_np2 =3D TRUE;=0A=
     } else {=0A=
         object->baseTexture.pow2Matrix[0] =3D  (((float)Width)  / =
((float)pow2Width));=0A=
         object->baseTexture.pow2Matrix[5] =3D  (((float)Height) / =
((float)pow2Height));=0A=
         object->baseTexture.pow2Matrix[10] =3D 1.0;=0A=
         object->baseTexture.pow2Matrix[15] =3D 1.0;=0A=
         object->target =3D GL_TEXTURE_2D;=0A=
+        object->cond_np2 =3D FALSE;=0A=
     }=0A=
     TRACE(" xf(%f) yf(%f)\n", object->baseTexture.pow2Matrix[0], =
object->baseTexture.pow2Matrix[5]);=0A=
 =0A=
@@ -7043,7 +7054,8 @@ static void updateSurfaceDesc(IWineD3DSurfaceImpl =
*surface, WINED3DPRESENT_PARAM=0A=
     }=0A=
     surface->currentDesc.Width =3D =
pPresentationParameters->BackBufferWidth;=0A=
     surface->currentDesc.Height =3D =
pPresentationParameters->BackBufferHeight;=0A=
-    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || =
GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {=0A=
+    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || =
GL_SUPPORT(ARB_TEXTURE_RECTANGLE) ||=0A=
+        GL_SUPPORT(WINE_NORMALIZED_TEXRECT)) {=0A=
         surface->pow2Width =3D pPresentationParameters->BackBufferWidth;=0A=
         surface->pow2Height =3D =
pPresentationParameters->BackBufferHeight;=0A=
     } else {=0A=
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c=0A=
index bb559aa..c9b5c09 100644=0A=
--- a/dlls/wined3d/directx.c=0A=
+++ b/dlls/wined3d/directx.c=0A=
@@ -81,7 +81,7 @@ static const struct {=0A=
     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3,       =
    0                           },=0A=
     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT,          =
    0                           },=0A=
     {"GL_ARB_texture_mirrored_repeat",      =
ARB_TEXTURE_MIRRORED_REPEAT,    0                           },=0A=
-    {"GL_ARB_texture_non_power_of_two",     =
ARB_TEXTURE_NON_POWER_OF_TWO,   0                           },=0A=
+    {"GL_ARB_texture_non_power_of_two",     =
ARB_TEXTURE_NON_POWER_OF_TWO,   MAKEDWORD_VERSION(2, 0)     },=0A=
     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,      =
    0                           },=0A=
     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,           =
    0                           },=0A=
     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,   =
    0                           },=0A=
@@ -3677,21 +3677,6 @@ static void fixup_extensions(WineD3D_GL_Info =
*gl_info) {=0A=
             gl_info->vs_glsl_constantsF =3D gl_info->vs_arb_constantsF;=0A=
         }=0A=
 =0A=
-        /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 =
and earlier cards, although=0A=
-         * these cards only support =
GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).=0A=
-         * If real NP2 textures are used, the driver falls back to =
software. So remove the supported=0A=
-         * flag for this extension=0A=
-         */=0A=
-        if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && =
gl_info->gl_vendor =3D=3D VENDOR_ATI) {=0A=
-            if(gl_info->gl_card =3D=3D CARD_ATI_RADEON_X700 || =
gl_info->gl_card =3D=3D CARD_ATI_RADEON_X1600 ||=0A=
-               gl_info->gl_card =3D=3D CARD_ATI_RADEON_9500 || =
gl_info->gl_card =3D=3D CARD_ATI_RADEON_8500  ||=0A=
-               gl_info->gl_card =3D=3D CARD_ATI_RADEON_7200 || =
gl_info->gl_card =3D=3D CARD_ATI_RAGE_128PRO) {=0A=
-                TRACE("GL_ARB_texture_non_power_of_two advertised on =
R500 or earlier card, removing\n");=0A=
-                gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] =3D =
FALSE;=0A=
-                gl_info->supported[ARB_TEXTURE_RECTANGLE] =3D TRUE;=0A=
-            }=0A=
-        }=0A=
-=0A=
         /* The Intel GPUs on MacOS set the .w register of texcoords to =
0.0 by default, which causes problems=0A=
          * with fixed function fragment processing. Ideally this flag =
should be detected with a test shader=0A=
          * and OpenGL feedback mode, but some GL implementations (MacOS =
ATI at least, probably all MacOS ones)=0A=
@@ -3713,6 +3698,28 @@ static void fixup_extensions(WineD3D_GL_Info =
*gl_info) {=0A=
         }=0A=
     }=0A=
 =0A=
+    /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and =
earlier cards, although=0A=
+     * these cards only support =
GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).=0A=
+     * If real NP2 textures are used, the driver falls back to =
software. We could just remove the=0A=
+     * extension and use GL_ARB_texture_rectangle instead, but =
texture_rectangle is inconventient=0A=
+     * due to the non-normalized texture coordinates. Thus set an =
internal extension flag,=0A=
+     * GL_WINE_normalized_texrect, which signals the code that it can =
use non power of two textures=0A=
+     * as per GL_ARB_texture_non_power_of_two, but has to stick to the =
texture_rectangle limits.=0A=
+     *=0A=
+     * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it =
advertises opengl 2.0 which=0A=
+     * has this extension promoted to core. The extension loading code =
sets this extension supported=0A=
+     * due to that, so this code works on fglrx as well.=0A=
+     */=0A=
+    if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && =
gl_info->gl_vendor =3D=3D VENDOR_ATI) {=0A=
+        if(gl_info->gl_card =3D=3D CARD_ATI_RADEON_X700 || =
gl_info->gl_card =3D=3D CARD_ATI_RADEON_X1600 ||=0A=
+            gl_info->gl_card =3D=3D CARD_ATI_RADEON_9500 || =
gl_info->gl_card =3D=3D CARD_ATI_RADEON_8500  ||=0A=
+            gl_info->gl_card =3D=3D CARD_ATI_RADEON_7200 || =
gl_info->gl_card =3D=3D CARD_ATI_RAGE_128PRO) {=0A=
+            TRACE("GL_ARB_texture_non_power_of_two advertised on R500 =
or earlier card, removing\n");=0A=
+            gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] =3D FALSE;=0A=
+            gl_info->supported[WINE_NORMALIZED_TEXRECT] =3D TRUE;=0A=
+        }=0A=
+    }=0A=
+=0A=
     /* Find out if PBOs work as they are supposed to */=0A=
     test_pbo_functionality(gl_info);=0A=
 =0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 1237611..01ee006 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -4300,20 +4300,28 @@ const struct StateEntryTemplate =
ffp_vertexstate_template[] =3D {=0A=
      * otherwise, register sampler_texmatrix, which takes care of =
updating the texture matrix=0A=
      */=0A=
     { STATE_SAMPLER(0),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(0),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(0),                                   { =
STATE_SAMPLER(0),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(1),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(1),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(1),                                   { =
STATE_SAMPLER(1),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(2),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(2),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(2),                                   { =
STATE_SAMPLER(2),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(3),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(3),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(3),                                   { =
STATE_SAMPLER(3),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(4),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(4),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(4),                                   { =
STATE_SAMPLER(4),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(5),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(5),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(5),                                   { =
STATE_SAMPLER(5),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(6),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(6),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(6),                                   { =
STATE_SAMPLER(6),                                   sampler_texmatrix   =
}, 0                               },=0A=
     { STATE_SAMPLER(7),                                   { 0,          =
                                        NULL                }, =
ARB_TEXTURE_NON_POWER_OF_TWO    },=0A=
+    { STATE_SAMPLER(7),                                   { 0,          =
                                        NULL                }, =
WINE_NORMALIZED_TEXRECT         },=0A=
     { STATE_SAMPLER(7),                                   { =
STATE_SAMPLER(7),                                   sampler_texmatrix   =
}, 0                               },=0A=
     {0 /* Terminate */,                                   { 0,          =
                                        0                   }, 0         =
                      },=0A=
 };=0A=
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c=0A=
index 53070f2..cd312bc 100644=0A=
--- a/dlls/wined3d/surface.c=0A=
+++ b/dlls/wined3d/surface.c=0A=
@@ -3755,7 +3755,7 @@ static HRESULT WINAPI =
IWineD3DSurfaceImpl_PrivateSetup(IWineD3DSurface *iface) {=0A=
     This->glDescription.target           =3D GL_TEXTURE_2D;=0A=
 =0A=
     /* Non-power2 support */=0A=
-    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO)) {=0A=
+    if (GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) || =
GL_SUPPORT(WINE_NORMALIZED_TEXRECT)) {=0A=
         pow2Width =3D This->currentDesc.Width;=0A=
         pow2Height =3D This->currentDesc.Height;=0A=
     } else {=0A=
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c=0A=
index 9c50da6..5dc9821 100644=0A=
--- a/dlls/wined3d/texture.c=0A=
+++ b/dlls/wined3d/texture.c=0A=
@@ -245,6 +245,13 @@ static UINT WINAPI =
IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *ifa=0A=
     return This->target;=0A=
 }=0A=
 =0A=
+static BOOL WINAPI IWineD3DTextureImpl_IsCondNP2(IWineD3DTexture =
*iface) {=0A=
+    IWineD3DTextureImpl *This =3D (IWineD3DTextureImpl *)iface;=0A=
+    TRACE("(%p)\n", This);=0A=
+=0A=
+    return This->cond_np2;=0A=
+}=0A=
+=0A=
 static void WINAPI =
IWineD3DTextureImpl_ApplyStateChanges(IWineD3DTexture *iface,=0A=
                                                    const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],=0A=
                                                    const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {=0A=
@@ -370,6 +377,7 @@ const IWineD3DTextureVtbl IWineD3DTexture_Vtbl =3D=0A=
     IWineD3DTextureImpl_BindTexture,=0A=
     IWineD3DTextureImpl_UnBindTexture,=0A=
     IWineD3DTextureImpl_GetTextureDimensions,=0A=
+    IWineD3DTextureImpl_IsCondNP2,=0A=
     IWineD3DTextureImpl_ApplyStateChanges,=0A=
     /* IWineD3DTexture */=0A=
     IWineD3DTextureImpl_Destroy,=0A=
diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c=0A=
index 6639f9c..de0bba7 100644=0A=
--- a/dlls/wined3d/volumetexture.c=0A=
+++ b/dlls/wined3d/volumetexture.c=0A=
@@ -213,6 +213,13 @@ static UINT WINAPI =
IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolume=0A=
     return GL_TEXTURE_3D;=0A=
 }=0A=
 =0A=
+static BOOL WINAPI =
IWineD3DVolumeTextureImpl_IsCondNP2(IWineD3DVolumeTexture *iface) {=0A=
+    IWineD3DVolumeTextureImpl *This =3D (IWineD3DVolumeTextureImpl =
*)iface;=0A=
+    TRACE("(%p)\n", This);=0A=
+=0A=
+    return FALSE;=0A=
+}=0A=
+=0A=
 static void WINAPI =
IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface,=0A=
                                                         const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1],=0A=
                                                         const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) {=0A=
@@ -330,6 +337,7 @@ const IWineD3DVolumeTextureVtbl =
IWineD3DVolumeTexture_Vtbl =3D=0A=
     IWineD3DVolumeTextureImpl_BindTexture,=0A=
     IWineD3DVolumeTextureImpl_UnBindTexture,=0A=
     IWineD3DVolumeTextureImpl_GetTextureDimensions,=0A=
+    IWineD3DVolumeTextureImpl_IsCondNP2,=0A=
     IWineD3DVolumeTextureImpl_ApplyStateChanges,=0A=
     /* volume texture */=0A=
     IWineD3DVolumeTextureImpl_Destroy,=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index d69dcea..fdbb4a3 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -1120,6 +1120,7 @@ typedef struct IWineD3DTextureImpl=0A=
     UINT                      width;=0A=
     UINT                      height;=0A=
     UINT                      target;=0A=
+    BOOL                      cond_np2;=0A=
 =0A=
 } IWineD3DTextureImpl;=0A=
 =0A=
diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h=0A=
index 405ea68..04471df 100644=0A=
--- a/include/wine/wined3d_gl.h=0A=
+++ b/include/wine/wined3d_gl.h=0A=
@@ -3367,6 +3367,9 @@ typedef enum _GL_SupportedExt {=0A=
   SGI_VIDEO_SYNC,=0A=
   SGIS_GENERATE_MIPMAP,=0A=
 =0A=
+  /* Internally used */=0A=
+  WINE_NORMALIZED_TEXRECT,=0A=
+=0A=
   /* WGL extensions */=0A=
   WGL_ARB_PBUFFER,=0A=
   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,=0A=
diff --git a/include/wine/wined3d_interface.h =
b/include/wine/wined3d_interface.h=0A=
index c9b3853..76d5843 100644=0A=
--- a/include/wine/wined3d_interface.h=0A=
+++ b/include/wine/wined3d_interface.h=0A=
@@ -813,6 +813,7 @@ =
DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource)=0A=
     STDMETHOD(BindTexture)(THIS) PURE;=0A=
     STDMETHOD(UnBindTexture)(THIS) PURE;=0A=
     STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;=0A=
+    STDMETHOD_(BOOL, IsCondNP2)(THIS) PURE;=0A=
     STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;=0A=
 =0A=
 };=0A=
@@ -848,6 +849,7 @@ =
DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource)=0A=
 #define IWineD3DBaseTexture_BindTexture(p)             =
(p)->lpVtbl->BindTexture(p)=0A=
 #define IWineD3DBaseTexture_UnBindTexture(p)           =
(p)->lpVtbl->UnBindTexture(p)=0A=
 #define IWineD3DBaseTexture_GetTextureDimensions(p)    =
(p)->lpVtbl->GetTextureDimensions(p)=0A=
+#define IWineD3DBaseTexture_IsCondNP2(p)               =
(p)->lpVtbl->IsCondNP2(p)=0A=
 #define IWineD3DBaseTexture_ApplyStateChanges(p,a,b)   =
(p)->lpVtbl->ApplyStateChanges(p,a,b)=0A=
 #endif=0A=
 =0A=
@@ -885,6 +887,7 @@ =
DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture)=0A=
     STDMETHOD(BindTexture)(THIS) PURE;=0A=
     STDMETHOD(UnBindTexture)(THIS) PURE;=0A=
     STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;=0A=
+    STDMETHOD_(BOOL, IsCondNP2)(THIS) PURE;=0A=
     STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;=0A=
     /*** IWineD3DTexture methods ***/=0A=
     STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;=0A=
@@ -925,6 +928,7 @@ =
DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture)=0A=
 #define IWineD3DTexture_BindTexture(p)             =
(p)->lpVtbl->BindTexture(p)=0A=
 #define IWineD3DTexture_UnBindTexture(p)           =
(p)->lpVtbl->UnBindTexture(p)=0A=
 #define IWineD3DTexture_GetTextureDimensions(p)    =
(p)->lpVtbl->GetTextureDimensions(p)=0A=
+#define IWineD3DTexture_IsCondNP2(p)               =
(p)->lpVtbl->IsCondNP2(p)=0A=
 #define IWineD3DTexture_ApplyStateChanges(p,a,b)   =
(p)->lpVtbl->ApplyStateChanges(p,a,b)=0A=
 /*** IWineD3DTexture methods ***/=0A=
 #define IWineD3DTexture_Destroy(p,a)               =
(p)->lpVtbl->Destroy(p,a)=0A=
@@ -969,6 +973,7 @@ =
DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture)=0A=
     STDMETHOD(BindTexture)(THIS) PURE;=0A=
     STDMETHOD(UnBindTexture)(THIS) PURE;=0A=
     STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;=0A=
+    STDMETHOD_(BOOL, IsCondNP2)(THIS) PURE;=0A=
     STDMETHOD_(void, ApplyStateChanges)(THIS_ DWORD const =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;=0A=
     /*** IWineD3DCubeTexture methods ***/=0A=
     STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;=0A=
@@ -1009,6 +1014,7 @@ =
DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture)=0A=
 #define IWineD3DCubeTexture_BindTexture(p)              =
(p)->lpVtbl->BindTexture(p)=0A=
 #define IWineD3DCubeTexture_UnBindTexture(p)            =
(p)->lpVtbl->UnBindTexture(p)=0A=
 #define IWineD3DCubeTexture_GetTextureDimensions(p)     =
(p)->lpVtbl->GetTextureDimensions(p)=0A=
+#define IWineD3DCubeTexture_IsCondNP2(p)               =
(p)->lpVtbl->IsCondNP2(p)=0A=
 #define IWineD3DCubeTexture_ApplyStateChanges(p,a,b)   =
(p)->lpVtbl->ApplyStateChanges(p,a,b)=0A=
 /*** IWineD3DCubeTexture methods ***/=0A=
 #define IWineD3DCubeTexture_Destroy(p,a)               =
(p)->lpVtbl->Destroy(p,a)=0A=
@@ -1054,6 +1060,7 @@ =
DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture)=0A=
     STDMETHOD(BindTexture)(THIS) PURE;=0A=
     STDMETHOD(UnBindTexture)(THIS) PURE;=0A=
     STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE;=0A=
+    STDMETHOD_(BOOL, IsCondNP2)(THIS) PURE;=0A=
     STDMETHOD_(void, ApplyStateChanges)(THIS_ const DWORD =
textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD =
samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) PURE;=0A=
     /*** IWineD3DVolumeTexture methods ***/=0A=
     STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYVOLUMEFN pFn) PURE;=0A=
@@ -1094,6 +1101,7 @@ =
DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture)=0A=
 #define IWineD3DVolumeTexture_BindTexture(p)              =
(p)->lpVtbl->BindTexture(p)=0A=
 #define IWineD3DVolumeTexture_UnBindTexture(p)            =
(p)->lpVtbl->UnBindTexture(p)=0A=
 #define IWineD3DVolumeTexture_GetTextureDimensions(p)     =
(p)->lpVtbl->GetTextureDimensions(p)=0A=
+#define IWineD3DVolumeTexture_IsCondNP2(p)               =
(p)->lpVtbl->IsCondNP2(p)=0A=
 #define IWineD3DVolumeTexture_ApplyStateChanges(p,a,b)   =
(p)->lpVtbl->ApplyStateChanges(p,a,b)=0A=
 /*** IWineD3DVolumeTexture methods ***/=0A=
 #define IWineD3DVolumeTexture_Destroy(p,a)               =
(p)->lpVtbl->Destroy(p,a)=0A=
-- =0A=
1.5.4.5=0A=
=0A=

------=_NextPart_000_0026_01C8E844.D9182EC0--




More information about the wine-patches mailing list