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