static void texture_cleanup(IWineD3DBaseTextureImpl *This) { unsigned int i; TRACE("(%p) : Cleaning up\n", This); for (i = 0; i < This->baseTexture.level_count; ++i) { struct wined3d_resource *sub_resource = This->baseTexture.sub_resources[i]; if (sub_resource) { IWineD3DSurfaceImpl *surface = surface_from_resource(sub_resource); /* Clean out the texture name we gave to the surface so that the * surface doesn't try and release it */ surface_set_texture_name(surface, 0, TRUE); surface_set_texture_name(surface, 0, FALSE); surface_set_texture_target(surface, 0); surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); IWineD3DSurface_Release((IWineD3DSurface *)surface); } } TRACE("(%p) : Cleaning up base texture\n", This); basetexture_cleanup((IWineD3DBaseTextureImpl *)This); }
static void texture2d_sub_resource_cleanup(struct wined3d_resource *sub_resource) { struct wined3d_surface *surface = surface_from_resource(sub_resource); /* Clean out the texture name we gave to the surface so that the * surface doesn't try and release it. */ surface_set_texture_name(surface, 0, TRUE); surface_set_texture_name(surface, 0, FALSE); surface_set_texture_target(surface, 0, 0); surface_set_container(surface, WINED3D_CONTAINER_NONE, NULL); wined3d_surface_decref(surface); }
static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) { unsigned int i; IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; TRACE("(%p)\n", This); /* Unload all the surfaces and reset the texture name. If UnLoad was called on the * surface before, this one will be a NOP and vice versa. Unloading an unloaded * surface is fine */ for (i = 0; i < This->baseTexture.levels; i++) { IWineD3DSurface_UnLoad(This->surfaces[i]); surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */ surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */ } basetexture_unload((IWineD3DBaseTexture *)iface); }
/* 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; }
/* Context activation is done by the caller. */ static HRESULT texture2d_bind(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info, BOOL srgb) { BOOL set_gl_texture_desc; HRESULT hr; TRACE("texture %p, gl_info %p, srgb %#x.\n", texture, gl_info, srgb); hr = wined3d_texture_bind(texture, gl_info, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT sub_count = texture->level_count * texture->layer_count; BOOL srgb_tex = !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && (texture->flags & WINED3D_TEXTURE_IS_SRGB); struct gl_texture *gl_tex; UINT i; gl_tex = wined3d_texture_get_gl_texture(texture, gl_info, srgb_tex); for (i = 0; i < sub_count; ++i) { struct wined3d_surface *surface = surface_from_resource(texture->sub_resources[i]); surface_set_texture_name(surface, gl_tex->name, srgb_tex); } /* 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 (texture->flags & WINED3D_TEXTURE_COND_NP2) { GLenum target = texture->target; ENTER_GL(); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, 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; }
/* Context activation is done by the caller. */ static HRESULT texture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb) { BOOL set_gl_texture_desc; HRESULT hr; TRACE("texture %p, srgb %#x.\n", texture, srgb); hr = basetexture_bind(texture, srgb, &set_gl_texture_desc); if (set_gl_texture_desc && SUCCEEDED(hr)) { UINT i; struct gl_texture *gl_tex; if (texture->baseTexture.is_srgb) gl_tex = &texture->baseTexture.texture_srgb; else gl_tex = &texture->baseTexture.texture_rgb; for (i = 0; i < texture->baseTexture.level_count; ++i) { IWineD3DSurfaceImpl *surface = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[i]; surface_set_texture_name(surface, gl_tex->name, texture->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((IWineD3DBaseTexture *)texture)) { GLenum target = texture->baseTexture.target; ENTER_GL(); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); checkGLcall("glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)"); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)"); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); checkGLcall("glTexParameteri(target, 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; }
/* Do not call while under the GL lock. */ static void texture_unload(struct wined3d_resource *resource) { IWineD3DBaseTextureImpl *texture = basetexture_from_resource(resource); unsigned int i; TRACE("texture %p.\n", texture); for (i = 0; i < texture->baseTexture.level_count; ++i) { struct wined3d_resource *sub_resource = texture->baseTexture.sub_resources[i]; IWineD3DSurfaceImpl *surface = surface_from_resource(sub_resource); sub_resource->resource_ops->resource_unload(sub_resource); surface_set_texture_name(surface, 0, FALSE); /* Delete rgb name */ surface_set_texture_name(surface, 0, TRUE); /* delete srgb name */ } basetexture_unload(texture); }
/* Do not call while under the GL lock. */ static void texture2d_unload(struct wined3d_resource *resource) { struct wined3d_texture *texture = wined3d_texture_from_resource(resource); UINT sub_count = texture->level_count * texture->layer_count; UINT i; TRACE("texture %p.\n", texture); for (i = 0; i < sub_count; ++i) { struct wined3d_resource *sub_resource = texture->sub_resources[i]; struct wined3d_surface *surface = surface_from_resource(sub_resource); sub_resource->resource_ops->resource_unload(sub_resource); surface_set_texture_name(surface, 0, FALSE); /* Delete RGB name */ surface_set_texture_name(surface, 0, TRUE); /* Delete sRGB name */ } wined3d_texture_unload(texture); }
static void texture_cleanup(IWineD3DTextureImpl *This) { unsigned int i; TRACE("(%p) : Cleaning up\n", This); for (i = 0; i < This->baseTexture.levels; ++i) { if (This->surfaces[i]) { /* Clean out the texture name we gave to the surface so that the * surface doesn't try and release it */ surface_set_texture_name(This->surfaces[i], 0, TRUE); surface_set_texture_name(This->surfaces[i], 0, FALSE); surface_set_texture_target(This->surfaces[i], 0); IWineD3DSurface_SetContainer(This->surfaces[i], 0); IWineD3DSurface_Release(This->surfaces[i]); } } TRACE("(%p) : Cleaning up base texture\n", This); basetexture_cleanup((IWineD3DBaseTexture *)This); }