diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index aeece1ab512..857750d6bd7 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -618,13 +618,22 @@ void *resource_offset_map_pointer(struct wined3d_resource *resource, unsigned in void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, const struct wined3d_map_desc *map, const struct wined3d_color *colour, - const struct wined3d_box *box) + const struct wined3d_box *box, bool full_subresource) { const struct wined3d_format *format = resource->format; unsigned int w, h, d, x, y, z, bpp; uint8_t *dst, *dst2; uint32_t c[4]; + /* Fast and simple path for setting everything to zero. The C library's memset is + * more sophisticated than our code below. Also this works for block formats, which + * we still need to zero-initialize for newly created resources. */ + if (full_subresource && !colour->r && !colour->g && !colour->b && !colour->a) + { + memset(map->data, 0, map->slice_pitch * box->back); + return; + } + w = box->right - box->left; h = box->bottom - box->top; d = box->back - box->front; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 20a06b32d03..7d62af5b31f 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1181,8 +1181,10 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, struct wined3d_context *context; struct wined3d_texture *texture; struct wined3d_bo_address data; + struct wined3d_box level_box; struct wined3d_map_desc map; struct wined3d_range range; + bool full_subresource; unsigned int level; DWORD map_binding; @@ -1208,6 +1210,8 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, texture = texture_from_resource(view->resource); level = view->sub_resource_idx % texture->level_count; + wined3d_texture_get_level_box(texture_from_resource(view->resource), level, &level_box); + full_subresource = !memcmp(box, &level_box, sizeof(*box)); map_binding = texture->resource.map_binding; if (!wined3d_texture_load_location(texture, view->sub_resource_idx, context, map_binding)) @@ -1220,7 +1224,7 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view, range.offset = 0; range.size = texture->sub_resources[view->sub_resource_idx].size; - wined3d_resource_memory_colour_fill(view->resource, &map, colour, box); + wined3d_resource_memory_colour_fill(view->resource, &map, colour, box, full_subresource); wined3d_context_unmap_bo_address(context, &data, 1, &range); context_release(context); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ce4d7384066..dfb2d76c08a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4429,7 +4429,7 @@ BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource) DECLSPEC void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, const struct wined3d_map_desc *map, const struct wined3d_color *colour, - const struct wined3d_box *box) DECLSPEC_HIDDEN; + const struct wined3d_box *box, bool full_subresource) DECLSPEC_HIDDEN; /* Tests show that the start address of resources is 32 byte aligned */ #define RESOURCE_ALIGNMENT 16