Commit e6780a5e authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Evict system memory for complete textures.

parent 2066e1a9
...@@ -33,8 +33,6 @@ ...@@ -33,8 +33,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); 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 static const DWORD surface_simple_locations = WINED3D_LOCATION_SYSMEM
| WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER;
...@@ -429,19 +427,6 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface) ...@@ -429,19 +427,6 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
return WINED3D_OK; 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) static BOOL surface_is_full_rect(const struct wined3d_surface *surface, const RECT *r)
{ {
unsigned int t; unsigned int t;
...@@ -2531,8 +2516,6 @@ static HRESULT surface_blt_special(struct wined3d_surface *dst_surface, const RE ...@@ -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); fb_copy_to_texture_hwstretch(dst_surface, src_surface, src_rect, dst_rect, filter);
} }
surface_evict_sysmem(dst_surface);
return WINED3D_OK; return WINED3D_OK;
} }
...@@ -3153,9 +3136,6 @@ done: ...@@ -3153,9 +3136,6 @@ done:
surface->ds_current_size.cy = surface_h; 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; return WINED3D_OK;
} }
...@@ -4332,7 +4312,6 @@ cpu: ...@@ -4332,7 +4312,6 @@ cpu:
HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_texture *container, 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) 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; struct wined3d_device *device = container->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format); 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 ...@@ -4361,10 +4340,6 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
list_init(&surface->renderbuffers); list_init(&surface->renderbuffers);
list_init(&surface->overlays); 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; return hr;
} }
......
...@@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d); ...@@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf); WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
WINE_DECLARE_DEBUG_CHANNEL(winediag); 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) 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 return texture->resource.pool == WINED3D_POOL_DEFAULT
...@@ -69,16 +71,47 @@ GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) ...@@ -69,16 +71,47 @@ GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture)
return GL_BACK; 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, void wined3d_texture_validate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location) unsigned int sub_resource_idx, DWORD location)
{ {
struct wined3d_texture_sub_resource *sub_resource; struct wined3d_texture_sub_resource *sub_resource;
DWORD previous_locations;
TRACE("texture %p, sub_resource_idx %u, location %s.\n", TRACE("texture %p, sub_resource_idx %u, location %s.\n",
texture, sub_resource_idx, wined3d_debug_location(location)); texture, sub_resource_idx, wined3d_debug_location(location));
sub_resource = &texture->sub_resources[sub_resource_idx]; sub_resource = &texture->sub_resources[sub_resource_idx];
previous_locations = sub_resource->locations;
sub_resource->locations |= location; 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)); 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, ...@@ -96,6 +129,8 @@ void wined3d_texture_invalidate_location(struct wined3d_texture *texture,
sub_resource = &texture->sub_resources[sub_resource_idx]; sub_resource = &texture->sub_resources[sub_resource_idx];
sub_resource->locations &= ~location; 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)); 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 ...@@ -970,6 +1005,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
sub_resource->resource->width = width; sub_resource->resource->width = width;
sub_resource->resource->height = height; sub_resource->resource->height = height;
sub_resource->resource->size = texture->slice_pitch; 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] 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]) && !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 ...@@ -988,8 +1024,6 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
texture->pow2_height = height; texture->pow2_height = height;
} }
sub_resource->locations = 0;
if ((texture->user_memory = mem)) if ((texture->user_memory = mem))
{ {
texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY; texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
...@@ -1009,6 +1043,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT ...@@ -1009,6 +1043,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
texture->resource.map_binding = WINED3D_LOCATION_SYSMEM; texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
wined3d_texture_validate_location(texture, 0, valid_location); wined3d_texture_validate_location(texture, 0, valid_location);
wined3d_texture_invalidate_location(texture, 0, ~valid_location);
if (create_dib) if (create_dib)
wined3d_surface_create_dc(surface); wined3d_surface_create_dc(surface);
...@@ -1849,6 +1884,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 ...@@ -1849,6 +1884,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
}; };
GLenum target = desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP ? cube_targets[j] : texture->target; 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; unsigned int idx = j * texture->level_count + i;
struct wined3d_surface *surface; struct wined3d_surface *surface;
...@@ -1862,6 +1898,16 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 ...@@ -1862,6 +1898,16 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
return hr; 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, if (FAILED(hr = device_parent->ops->surface_created(device_parent,
texture, idx, &parent, &parent_ops))) texture, idx, &parent, &parent_ops)))
{ {
...@@ -1875,8 +1921,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 ...@@ -1875,8 +1921,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
surface->resource.parent = parent; surface->resource.parent = parent;
surface->resource.parent_ops = parent_ops; 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); TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
if (((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D)) if (((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
...@@ -2097,6 +2141,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct ...@@ -2097,6 +2141,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
volume_desc.resource_type = WINED3D_RTYPE_VOLUME; volume_desc.resource_type = WINED3D_RTYPE_VOLUME;
for (i = 0; i < texture->level_count; ++i) for (i = 0; i < texture->level_count; ++i)
{ {
struct wined3d_texture_sub_resource *sub_resource;
struct wined3d_volume *volume; struct wined3d_volume *volume;
volume = &volumes[i]; volume = &volumes[i];
...@@ -2109,6 +2154,11 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct ...@@ -2109,6 +2154,11 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
return hr; 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, if (FAILED(hr = device_parent->ops->volume_created(device_parent,
texture, i, &parent, &parent_ops))) texture, i, &parent, &parent_ops)))
{ {
...@@ -2122,8 +2172,6 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct ...@@ -2122,8 +2172,6 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
volume->resource.parent = parent; volume->resource.parent = parent;
volume->resource.parent_ops = parent_ops; 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); TRACE("Created volume level %u @ %p.\n", i, volume);
/* Calculate the next mipmap level. */ /* Calculate the next mipmap level. */
......
...@@ -121,12 +121,6 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, ...@@ -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) static DWORD volume_access_from_location(DWORD location)
{ {
switch (location) switch (location)
...@@ -174,20 +168,6 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, ...@@ -174,20 +168,6 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
HeapFree(GetProcessHeap(), 0, data.addr); 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. */ /* Context activation is done by the caller. */
BOOL wined3d_volume_load_location(struct wined3d_volume *volume, BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
struct wined3d_context *context, DWORD location) struct wined3d_context *context, DWORD location)
...@@ -308,9 +288,6 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume, ...@@ -308,9 +288,6 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
done: done:
wined3d_texture_validate_location(texture, sub_resource_idx, location); 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; return TRUE;
} }
...@@ -387,8 +364,6 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur ...@@ -387,8 +364,6 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
wined3d_resource_free_sysmem(&volume->resource); wined3d_resource_free_sysmem(&volume->resource);
volume->texture_level = level; volume->texture_level = level;
container->sub_resources[level].locations = WINED3D_LOCATION_DISCARDED;
volume->container = container; volume->container = container;
return WINED3D_OK; return WINED3D_OK;
......
...@@ -2467,6 +2467,7 @@ struct wined3d_texture ...@@ -2467,6 +2467,7 @@ struct wined3d_texture
UINT layer_count; UINT layer_count;
UINT level_count; UINT level_count;
unsigned int download_count; unsigned int download_count;
unsigned int sysmem_count;
float pow2_matrix[16]; float pow2_matrix[16];
UINT lod; UINT lod;
enum wined3d_texture_filter_type filter_type; enum wined3d_texture_filter_type filter_type;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment