From 3e3f5e88e6aa27ce3838d0faed9de135532f10a4 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 5 Apr 2017 10:21:25 +0200 Subject: [PATCH] wined3d: Send rendertarget view clears through the command stream. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/cs.c | 62 ++++++++++++++++++++++++++++++---- dlls/wined3d/device.c | 16 ++------- dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 841ceca5c86..c408eb04219 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -81,6 +81,9 @@ struct wined3d_cs_clear { enum wined3d_cs_op opcode; DWORD flags; + unsigned int rt_count; + struct wined3d_fb_state *fb; + RECT draw_rect; struct wined3d_color color; float depth; DWORD stencil; @@ -420,24 +423,25 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) device = cs->device; wined3d_get_draw_rect(state, &draw_rect); - device->blitter->ops->blitter_clear(device->blitter, device, device->adapter->gl_info.limits.buffers, - state->fb, op->rect_count, op->rects, &draw_rect, op->flags, &op->color, op->depth, op->stencil); + device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb, + op->rect_count, op->rects, &op->draw_rect, op->flags, &op->color, op->depth, op->stencil); if (op->flags & WINED3DCLEAR_TARGET) { - for (i = 0; i < device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < op->rt_count; ++i) { - if (state->fb->render_targets[i]) - wined3d_resource_release(state->fb->render_targets[i]->resource); + if (op->fb->render_targets[i]) + wined3d_resource_release(op->fb->render_targets[i]->resource); } } if (op->flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) - wined3d_resource_release(state->fb->depth_stencil->resource); + wined3d_resource_release(op->fb->depth_stencil->resource); } void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) { + unsigned int rt_count = cs->device->adapter->gl_info.limits.buffers; const struct wined3d_state *state = &cs->device->state; struct wined3d_cs_clear *op; unsigned int i; @@ -445,6 +449,9 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[rect_count])); op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags; + op->rt_count = rt_count; + op->fb = &cs->fb; + wined3d_get_draw_rect(state, &op->draw_rect); op->color = *color; op->depth = depth; op->stencil = stencil; @@ -453,7 +460,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * if (flags & WINED3DCLEAR_TARGET) { - for (i = 0; i < cs->device->adapter->gl_info.limits.buffers; ++i) + for (i = 0; i < rt_count; ++i) { if (state->fb->render_targets[i]) wined3d_resource_acquire(state->fb->render_targets[i]->resource); @@ -465,6 +472,47 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * cs->ops->submit(cs); } +void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) +{ + struct wined3d_cs_clear *op; + struct + { + struct wined3d_rendertarget_view *rt; + struct wined3d_fb_state fb; + } *extra; + + op = cs->ops->require_space(cs, FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(*extra)); + extra = (void *)&op->rects[1]; + extra->fb.render_targets = &extra->rt; + op->fb = &extra->fb; + + op->opcode = WINED3D_CS_OP_CLEAR; + op->flags = flags; + if (flags & WINED3DCLEAR_TARGET) + { + op->rt_count = 1; + op->fb->render_targets[0] = view; + op->fb->depth_stencil = NULL; + op->color = *color; + } + else + { + op->rt_count = 0; + op->fb->render_targets[0] = NULL; + op->fb->depth_stencil = view; + op->depth = depth; + op->stencil = stencil; + } + SetRect(&op->draw_rect, 0, 0, view->width, view->height); + op->rect_count = 1; + op->rects[0] = *rect; + + wined3d_resource_acquire(view->resource); + + cs->ops->submit(cs); +} + static void acquire_shader_resources(const struct wined3d_state *state, unsigned int shader_mask) { struct wined3d_shader_sampler_map_entry *entry; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 11a56f28885..ffc99b1a237 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4148,7 +4148,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi const struct wined3d_color *color, float depth, DWORD stencil) { struct wined3d_resource *resource; - RECT draw_rect, r; + RECT r; TRACE("device %p, view %p, rect %s, flags %#x, color %s, depth %.8e, stencil %u.\n", device, view, wine_dbgstr_rect(rect), flags, debug_color(color), depth, stencil); @@ -4185,19 +4185,7 @@ HRESULT CDECL wined3d_device_clear_rendertarget_view(struct wined3d_device *devi return hr; } - SetRect(&draw_rect, 0, 0, view->width, view->height); - if (flags == WINED3DCLEAR_TARGET) - { - struct wined3d_fb_state fb = {&view, NULL}; - device->blitter->ops->blitter_clear(device->blitter, device, 1, &fb, - 1, rect, &draw_rect, flags, color, depth, stencil); - } - else - { - struct wined3d_fb_state fb = {NULL, view}; - device->blitter->ops->blitter_clear(device->blitter, device, 0, &fb, - 1, rect, &draw_rect, flags, color, depth, stencil); - } + wined3d_cs_emit_clear_rendertarget_view(device->cs, view, rect, flags, color, depth, stencil); return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4acb94ff0bd..82aecf72be4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3228,6 +3228,8 @@ void wined3d_cs_emit_blt_sub_resource(struct wined3d_cs *cs, struct wined3d_reso const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN; void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; +void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view, + const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, int base_vertex_idx,