/* Context activation is done by the caller. */ static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) { IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; BOOL set_gl_texture_desc; HRESULT hr; TRACE("(%p) : relay to BaseTexture\n", This); #ifdef VBOX_WITH_WDDM Assert(!VBOXSHRC_IS_DISABLED(This)); #endif hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT i; struct gl_texture *gl_tex; if(This->baseTexture.is_srgb) { gl_tex = &This->baseTexture.texture_srgb; } else { gl_tex = &This->baseTexture.texture_rgb; } for (i = 0; i < This->baseTexture.levels; ++i) { surface_set_texture_name(This->surfaces[i], gl_tex->name, This->baseTexture.is_srgb); } /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something * that prevents us from hitting the accelerated codepath. Thus manually set the GL state. The same applies to filtering. * Even if the texture has only one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW fallback on macos. */ if(IWineD3DBaseTexture_IsCondNP2(iface)) { #ifdef VBOX_WITH_WDDM if (!VBOXSHRC_IS_SHARED_OPENED(This)) #endif { ENTER_GL(); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(IWineD3DTexture_GetTextureDimensions(iface), GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); LEAVE_GL(); } gl_tex->states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_CLAMP; gl_tex->states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_NONE; } } return hr; }
static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { /* Override the IWineD3DResource PreLoad method */ unsigned int i; BOOL setGlTextureDesc = FALSE; IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; TRACE("(%p) : About to load texture\n", This); if (This->baseTexture.textureName == 0) setGlTextureDesc = TRUE; IWineD3DTexture_BindTexture(iface); ENTER_GL(); /* If were dirty then reload the surfaces */ if(This->baseTexture.dirty != FALSE) { for (i = 0; i < This->baseTexture.levels; i++) { if(setGlTextureDesc) IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface)); IWineD3DSurface_LoadTexture(This->surfaces[i]); } /* No longer dirty */ This->baseTexture.dirty = FALSE; } else { TRACE("(%p) Texture not dirty, nothing to do\n" , iface); } LEAVE_GL(); return ; }