wined3d: Evict system memory for complete textures.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2016-04-20 19:29:11 +02:00 committed by Alexandre Julliard
parent 2066e1a962
commit e6780a5e05
4 changed files with 55 additions and 56 deletions

View File

@ -33,8 +33,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy. */
static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM
| WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER;
@ -429,19 +427,6 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
return WINED3D_OK;
}
static void surface_evict_sysmem(struct wined3d_surface *surface)
{
unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
struct wined3d_texture *texture = surface->container;
if (texture->sub_resources[sub_resource_idx].map_count || texture->download_count > MAXLOCKCOUNT
|| texture->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM))
return;
wined3d_resource_free_sysmem(&surface->resource);
wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM);
}
static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
{
unsigned int t;
@ -2531,8 +2516,6 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE
fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter);
}
surface_evict_sysmem(dst_surface);
return WINED3D_OK;
}
@ -3153,9 +3136,6 @@ done:
surface->ds_current_size.cy = surface_h;
}
if (location != WINED3D_LOCATION_SYSMEM && (sub_resource->locations & WINED3D_LOCATION_SYSMEM))
surface_evict_sysmem(surface);
return WINED3D_OK;
}
@ -4332,7 +4312,6 @@ cpu:
HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_texture *container,
const struct wined3d_resource_desc *desc, GLenum target, unsigned int level, unsigned int layer)
{
unsigned int sub_resource_idx = layer * container->level_count + level;
struct wined3d_device *device = container->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
@ -4361,10 +4340,6 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
list_init(&surface->renderbuffers);
list_init(&surface->overlays);
wined3d_texture_validate_location(container, sub_resource_idx, WINED3D_LOCATION_SYSMEM);
if (container->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
container->sub_resources[sub_resource_idx].locations = WINED3D_LOCATION_DISCARDED;
return hr;
}

View File

@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
#define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50
static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
{
return texture->resource.pool == WINED3D_POOL_DEFAULT
@ -69,16 +71,47 @@ GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture)
return GL_BACK;
}
static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
{
struct wined3d_texture_sub_resource *sub_resource;
unsigned int i, sub_count;
if (texture->flags & (WINED3D_TEXTURE_CONVERTED | WINED3D_TEXTURE_PIN_SYSMEM)
|| texture->download_count > WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD)
{
TRACE("Not evicting system memory for texture %p.\n", texture);
return;
}
TRACE("Evicting system memory for texture %p.\n", texture);
sub_count = texture->level_count * texture->layer_count;
for (i = 0; i < sub_count; ++i)
{
sub_resource = &texture->sub_resources[i];
if (sub_resource->locations == WINED3D_LOCATION_SYSMEM)
ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n",
i, texture);
sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM;
wined3d_resource_free_sysmem(sub_resource->resource);
}
}
void wined3d_texture_validate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location)
{
struct wined3d_texture_sub_resource *sub_resource;
DWORD previous_locations;
TRACE("texture %p, sub_resource_idx %u, location %s.\n",
texture, sub_resource_idx, wined3d_debug_location(location));
sub_resource = &texture->sub_resources[sub_resource_idx];
previous_locations = sub_resource->locations;
sub_resource->locations |= location;
if (previous_locations == WINED3D_LOCATION_SYSMEM && location != WINED3D_LOCATION_SYSMEM
&& !--texture->sysmem_count)
wined3d_texture_evict_sysmem(texture);
TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
}
@ -96,6 +129,8 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
sub_resource = &texture->sub_resources[sub_resource_idx];
sub_resource->locations &= ~location;
if (sub_resource->locations == WINED3D_LOCATION_SYSMEM)
++texture->sysmem_count;
TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
@ -970,6 +1005,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
sub_resource->resource->width = width;
sub_resource->resource->height = height;
sub_resource->resource->size = texture->slice_pitch;
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
&& !gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
@ -988,8 +1024,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
texture->pow2_height = height;
}
sub_resource->locations = 0;
if ((texture->user_memory = mem))
{
texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
@ -1009,6 +1043,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
wined3d_texture_validate_location(texture, 0, valid_location);
wined3d_texture_invalidate_location(texture, 0, ~valid_location);
if (create_dib)
wined3d_surface_create_dc(surface);
@ -1849,6 +1884,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
};
GLenum target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target;
struct wined3d_texture_sub_resource *sub_resource;
unsigned int idx = j * texture->level_count + i;
struct wined3d_surface *surface;
@ -1862,6 +1898,16 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
return hr;
}
sub_resource = &texture->sub_resources[idx];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
sub_resource->resource = &surface->resource;
sub_resource->u.surface = surface;
if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
{
wined3d_texture_validate_location(texture, idx, WINED3D_LOCATION_SYSMEM);
wined3d_texture_invalidate_location(texture, idx, ~WINED3D_LOCATION_SYSMEM);
}
if (FAILED(hr = device_parent->ops->surface_created(device_parent,
texture, idx, &parent, &parent_ops)))
{
@ -1875,8 +1921,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
surface->resource.parent = parent;
surface->resource.parent_ops = parent_ops;
texture->sub_resources[idx].resource = &surface->resource;
texture->sub_resources[idx].u.surface = surface;
TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
if (((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
@ -2097,6 +2141,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
volume_desc.resource_type = WINED3D_RTYPE_VOLUME;
for (i = 0; i < texture->level_count; ++i)
{
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_volume *volume;
volume = &volumes[i];
@ -2109,6 +2154,11 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
return hr;
}
sub_resource = &texture->sub_resources[i];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
sub_resource->resource = &volume->resource;
sub_resource->u.volume = volume;
if (FAILED(hr = device_parent->ops->volume_created(device_parent,
texture, i, &parent, &parent_ops)))
{
@ -2122,8 +2172,6 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
volume->resource.parent = parent;
volume->resource.parent_ops = parent_ops;
texture->sub_resources[i].resource = &volume->resource;
texture->sub_resources[i].u.volume = volume;
TRACE("Created volume level %u @ %p.\n", i, volume);
/* Calculate the next mipmap level. */

View File

@ -121,12 +121,6 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume,
}
static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume)
{
wined3d_resource_free_sysmem(&volume->resource);
wined3d_texture_invalidate_location(volume->container, volume->texture_level, WINED3D_LOCATION_SYSMEM);
}
static DWORD volume_access_from_location(DWORD location)
{
switch (location)
@ -174,20 +168,6 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
HeapFree(GetProcessHeap(), 0, data.addr);
}
static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume)
{
struct wined3d_texture *texture = volume->container;
if (texture->resource.pool != WINED3D_POOL_MANAGED)
return FALSE;
if (texture->download_count >= 10)
return FALSE;
if (texture->resource.format->convert)
return FALSE;
return TRUE;
}
/* Context activation is done by the caller. */
BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
struct wined3d_context *context, DWORD location)
@ -308,9 +288,6 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
done:
wined3d_texture_validate_location(texture, sub_resource_idx, location);
if (location != WINED3D_LOCATION_SYSMEM && wined3d_volume_can_evict(volume))
wined3d_volume_evict_sysmem(volume);
return TRUE;
}
@ -387,8 +364,6 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
wined3d_resource_free_sysmem(&volume->resource);
volume->texture_level = level;
container->sub_resources[level].locations = WINED3D_LOCATION_DISCARDED;
volume->container = container;
return WINED3D_OK;

View File

@ -2467,6 +2467,7 @@ struct wined3d_texture
UINT layer_count;
UINT level_count;
unsigned int download_count;
unsigned int sysmem_count;
float pow2_matrix[16];
UINT lod;
enum wined3d_texture_filter_type filter_type;