Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/texture.c | 58 +++++++++++++++++++++++++++------- dlls/wined3d/wined3d_private.h | 3 ++ 2 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index c495de171d5..18fd0847296 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -816,17 +816,8 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
if (current & WINED3D_LOCATION_CLEARED) { - struct wined3d_bo_address addr; - - /* FIXME: Clear textures on the GPU if possible. */ - - if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM)) - return FALSE; - wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); - memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); - wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); - current |= WINED3D_LOCATION_SYSMEM; - + texture->texture_ops->texture_clear(texture, sub_resource_idx, context, location); + current = texture->sub_resources[sub_resource_idx].locations; if (current & location) return TRUE; } @@ -3447,6 +3438,20 @@ static void wined3d_texture_gl_unload_location(struct wined3d_texture *texture, } }
+static void wined3d_texture_gl_clear(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) +{ + struct wined3d_bo_address addr; + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); +} + static const struct wined3d_texture_ops texture_gl_ops = { wined3d_texture_gl_prepare_location, @@ -3454,6 +3459,7 @@ static const struct wined3d_texture_ops texture_gl_ops = wined3d_texture_gl_unload_location, wined3d_texture_gl_upload_data, wined3d_texture_gl_download_data, + wined3d_texture_gl_clear, };
struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource) @@ -4681,6 +4687,20 @@ static void wined3d_texture_no3d_unload_location(struct wined3d_texture *texture TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location)); }
+static void wined3d_texture_no3d_clear(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) +{ + struct wined3d_bo_address addr; + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); +} + static const struct wined3d_texture_ops wined3d_texture_no3d_ops = { wined3d_texture_no3d_prepare_location, @@ -4688,6 +4708,7 @@ static const struct wined3d_texture_ops wined3d_texture_no3d_ops = wined3d_texture_no3d_unload_location, wined3d_texture_no3d_upload_data, wined3d_texture_no3d_download_data, + wined3d_texture_no3d_clear, };
HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device, @@ -5458,6 +5479,20 @@ static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture, } }
+static void wined3d_texture_vk_clear(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location) +{ + struct wined3d_bo_address addr; + + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM); + wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM); + memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size); + wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM); +} + static const struct wined3d_texture_ops wined3d_texture_vk_ops = { wined3d_texture_vk_prepare_location, @@ -5465,6 +5500,7 @@ static const struct wined3d_texture_ops wined3d_texture_vk_ops = wined3d_texture_vk_unload_location, wined3d_texture_vk_upload_data, wined3d_texture_vk_download_data, + wined3d_texture_vk_clear, };
HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 54bccb3db5e..9cfb3a217d2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4393,6 +4393,9 @@ struct wined3d_texture_ops const struct wined3d_bo_address *dst_bo_addr, const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, unsigned int dst_row_pitch, unsigned int dst_slice_pitch); + /* "location" is a hint, and need not be the resulting location. */ + void (*texture_clear)(struct wined3d_texture *texture, unsigned int sub_resource_idx, + struct wined3d_context *context, unsigned int location); };
#define WINED3D_TEXTURE_COND_NP2 0x00000001