[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