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:
parent
2066e1a962
commit
e6780a5e05
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue