[PATCH 3/7] wined3d: Evict system memory for complete textures.
Henri Verbeet
hverbeet at codeweavers.com
Wed Apr 20 12:29:11 CDT 2016
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/surface.c | 25 ------------------
dlls/wined3d/texture.c | 60 +++++++++++++++++++++++++++++++++++++-----
dlls/wined3d/volume.c | 25 ------------------
dlls/wined3d/wined3d_private.h | 1 +
4 files changed, 55 insertions(+), 56 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 7a71193..075de5f 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -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;
}
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index ada571c..047e12d 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -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. */
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index ce3809f..6a92211 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -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;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f630223..4f06796 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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;
--
2.1.4
More information about the wine-patches
mailing list