Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 38 +++++++++++++++++------- dlls/wined3d/cs.c | 53 ++++++++++++++++++++-------------- dlls/wined3d/device.c | 37 ++++++++++++++---------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 5 ++-- include/wine/wined3d.h | 5 ++-- 6 files changed, 87 insertions(+), 53 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index b6e60050f4f..0ba195b73eb 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -552,20 +552,29 @@ static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *ifac wined3d_mutex_unlock(); }
-static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *iface, - enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) +static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int buffer_count, ID3D11Buffer *const *buffers) { + struct wined3d_buffer *wined3d_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int i;
- wined3d_mutex_lock(); + if (buffer_count > ARRAY_SIZE(wined3d_buffers)) + { + WARN("Buffer count %u exceeds limit; ignoring call.\n", buffer_count); + return; + } + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]);
- wined3d_device_context_set_constant_buffer(context->wined3d_context, type, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL); + wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL; } + + wined3d_mutex_lock(); + wined3d_device_context_set_constant_buffers(context->wined3d_context, + type, start_slot, buffer_count, wined3d_buffers); wined3d_mutex_unlock(); }
@@ -4554,20 +4563,29 @@ static void d3d10_device_get_constant_buffers(ID3D10Device1 *iface, wined3d_mutex_unlock(); }
-static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, - enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) +static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int buffer_count, ID3D10Buffer *const *buffers) { + struct wined3d_buffer *wined3d_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; struct d3d_device *device = impl_from_ID3D10Device(iface); unsigned int i;
- wined3d_mutex_lock(); + if (buffer_count > ARRAY_SIZE(wined3d_buffers)) + { + WARN("Buffer count %u exceeds limit; ignoring call.\n", buffer_count); + return; + } + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]);
- wined3d_device_context_set_constant_buffer(device->immediate_context.wined3d_context, type, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL); + wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL; } + + wined3d_mutex_lock(); + wined3d_device_context_set_constant_buffers(device->immediate_context.wined3d_context, + type, start_slot, buffer_count, wined3d_buffers); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index a7652380e16..712a20696a4 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -116,7 +116,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, WINED3D_CS_OP_SET_STREAM_OUTPUT, WINED3D_CS_OP_SET_INDEX_BUFFER, - WINED3D_CS_OP_SET_CONSTANT_BUFFER, + WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_TEXTURE, WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW, WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, @@ -282,12 +282,13 @@ struct wined3d_cs_set_index_buffer unsigned int offset; };
-struct wined3d_cs_set_constant_buffer +struct wined3d_cs_set_constant_buffers { enum wined3d_cs_op opcode; enum wined3d_shader_type type; - UINT cb_idx; - struct wined3d_buffer *buffer; + unsigned int start_idx; + unsigned int count; + struct wined3d_buffer *buffers[1]; };
struct wined3d_cs_set_texture @@ -603,7 +604,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUT); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); - WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); @@ -1535,32 +1536,40 @@ void wined3d_device_context_emit_set_index_buffer(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_constant_buffers(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_constant_buffer *op = data; - struct wined3d_buffer *prev; + const struct wined3d_cs_set_constant_buffers *op = data; + unsigned int i;
- prev = cs->state.cb[op->type][op->cb_idx]; - cs->state.cb[op->type][op->cb_idx] = op->buffer; + for (i = 0; i < op->count; ++i) + { + struct wined3d_buffer *prev = cs->state.cb[op->type][op->start_idx + i]; + struct wined3d_buffer *buffer = op->buffers[i];
- if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); + cs->state.cb[op->type][op->start_idx + i] = buffer; + + if (buffer) + InterlockedIncrement(&buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + }
device_invalidate_state(cs->c.device, STATE_CONSTANT_BUFFER(op->type)); }
-void wined3d_device_context_emit_set_constant_buffer(struct wined3d_device_context *context, - enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) +void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_buffer *const *buffers) { - struct wined3d_cs_set_constant_buffer *op; + struct wined3d_cs_set_constant_buffers *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; + op = wined3d_device_context_require_space(context, offsetof(struct wined3d_cs_set_constant_buffers, buffers[count]), + WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFERS; op->type = type; - op->cb_idx = cb_idx; - op->buffer = buffer; + op->start_idx = start_idx; + op->count = count; + memcpy(op->buffers, buffers, count * sizeof(*buffers));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2911,7 +2920,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, - /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, + /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c6b0c9f831e..f0aa9fbd250 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1696,8 +1696,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) { wined3d_device_context_emit_set_shader(context, i, state->shader[i]); - for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) - wined3d_device_context_emit_set_constant_buffer(context, i, j, state->cb[i][j]); + wined3d_device_context_emit_set_constant_buffers(context, i, 0, MAX_CONSTANT_BUFFERS, state->cb[i]); for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j) { wined3d_device_context_emit_set_sampler(context, i, j, state->sampler[i][j]); @@ -1832,30 +1831,36 @@ struct wined3d_shader * CDECL wined3d_device_context_get_shader(const struct win return context->state->shader[type]; }
-void CDECL wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_buffer *buffer) +void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_buffer *const *buffers) { struct wined3d_state *state = context->state; - struct wined3d_buffer *prev; + unsigned int i;
- TRACE("context %p, type %#x, idx %u, buffer %p.\n", context, type, idx, buffer); + TRACE("context %p, type %#x, start_idx %u, count %u, buffers %p.\n", context, type, start_idx, count, buffers);
- if (idx >= MAX_CONSTANT_BUFFERS) + if (start_idx + count > MAX_CONSTANT_BUFFERS) { - WARN("Invalid constant buffer index %u.\n", idx); + WARN("Invalid constant buffer index %u, count %u.\n", start_idx, count); return; }
- prev = state->cb[type][idx]; - if (buffer == prev) + if (!memcmp(buffers, &state->cb[type][start_idx], count * sizeof(*buffers))) return;
- if (buffer) - wined3d_buffer_incref(buffer); - state->cb[type][idx] = buffer; - wined3d_device_context_emit_set_constant_buffer(context, type, idx, buffer); - if (prev) - wined3d_buffer_decref(prev); + wined3d_device_context_emit_set_constant_buffers(context, type, start_idx, count, buffers); + for (i = 0; i < count; ++i) + { + struct wined3d_buffer *prev = state->cb[type][start_idx + i]; + struct wined3d_buffer *buffer = buffers[i]; + + if (buffer) + wined3d_buffer_incref(buffer); + state->cb[type][start_idx + i] = buffer; + if (prev) + wined3d_buffer_decref(prev); + } }
void CDECL wined3d_device_context_set_blend_state(struct wined3d_device_context *context, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 1369fd4cf90..3f22af60689 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -122,7 +122,7 @@ @ cdecl wined3d_device_context_reset_state(ptr) @ cdecl wined3d_device_context_resolve_sub_resource(ptr ptr long ptr long long) @ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long) -@ cdecl wined3d_device_context_set_constant_buffer(ptr long long ptr) +@ cdecl wined3d_device_context_set_constant_buffers(ptr long long long ptr) @ cdecl wined3d_device_context_set_depth_stencil_state(ptr ptr long) @ cdecl wined3d_device_context_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_context_set_index_buffer(ptr ptr long long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 12f1d21e6a0..afdea25ded9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4788,8 +4788,9 @@ void wined3d_device_context_emit_set_blend_state(struct wined3d_device_context * unsigned int sample_mask) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_clip_plane(struct wined3d_device_context *context, unsigned int plane_idx, const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_constant_buffer(struct wined3d_device_context *context, - enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_buffer *const *buffers) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_depth_stencil_state(struct wined3d_device_context *context, struct wined3d_depth_stencil_state *state, unsigned int stencil_ref) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 7777e45ad21..2e01d27ed68 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2494,8 +2494,9 @@ void __cdecl wined3d_device_context_resolve_sub_resource(struct wined3d_device_c struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, enum wined3d_format_id format_id); void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_context *context, struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask); -void __cdecl wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_buffer *buffer); +void __cdecl wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_buffer *const *buffers); void __cdecl wined3d_device_context_set_depth_stencil_state(struct wined3d_device_context *context, struct wined3d_depth_stencil_state *depth_stencil_state, unsigned int stencil_ref); HRESULT __cdecl wined3d_device_context_set_depth_stencil_view(struct wined3d_device_context *context,
Avoid storing pointers to the CS data inside individual ops, so that we can reallocate the queue when appending data to a deferred context, or copy the queue contents to a command list.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 14076defaa9..8702ac08631 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -107,7 +107,7 @@ struct wined3d_cs_clear enum wined3d_cs_op opcode; DWORD flags; unsigned int rt_count; - struct wined3d_fb_state *fb; + struct wined3d_fb_state fb; RECT draw_rect; struct wined3d_color color; float depth; @@ -684,19 +684,19 @@ static void wined3d_cs_exec_clear(struct wined3d_cs *cs, const void *data) const struct wined3d_cs_clear *op = data; unsigned int i;
- device->blitter->ops->blitter_clear(device->blitter, device, op->rt_count, op->fb, + 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 < op->rt_count; ++i) { - if (op->fb->render_targets[i]) - wined3d_resource_release(op->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(op->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, @@ -715,7 +715,7 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); op->rt_count = rt_count; - op->fb = &cs->state.fb; + op->fb = state->fb; SetRect(&op->draw_rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height); if (state->rasterizer_state && state->rasterizer_state->desc.scissor) IntersectRect(&op->draw_rect, &op->draw_rect, &state->scissor_rects[0]); @@ -746,24 +746,23 @@ void wined3d_device_context_emit_clear_rendertarget_view(struct wined3d_device_c struct wined3d_cs_clear *op; size_t size;
- size = FIELD_OFFSET(struct wined3d_cs_clear, rects[1]) + sizeof(struct wined3d_fb_state); + size = FIELD_OFFSET(struct wined3d_cs_clear, rects[1]); op = wined3d_device_context_require_space(context, size, WINED3D_CS_QUEUE_DEFAULT); - op->fb = (void *)&op->rects[1];
op->opcode = WINED3D_CS_OP_CLEAR; op->flags = flags & (WINED3DCLEAR_TARGET | WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); if (flags & WINED3DCLEAR_TARGET) { op->rt_count = 1; - op->fb->render_targets[0] = view; - op->fb->depth_stencil = NULL; + 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->fb.render_targets[0] = NULL; + op->fb.depth_stencil = view; op->depth = depth; op->stencil = stencil; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42191 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/d3d11_private.h | 1 + dlls/d3d11/device.c | 70 +++++++++++++++--- dlls/d3d11/tests/d3d11.c | 65 +++++++++-------- dlls/wined3d/cs.c | 146 +++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 3 + include/wine/wined3d.h | 3 + 6 files changed, 249 insertions(+), 39 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 1a8cdc6d77c..2b5a51afbd1 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -547,6 +547,7 @@ struct d3d11_device_context ID3D11Multithread ID3D11Multithread_iface; LONG refcount;
+ D3D11_DEVICE_CONTEXT_TYPE type; struct wined3d_device_context *wined3d_context; struct d3d_device *device;
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 2a012fce144..459c49145cd 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -351,7 +351,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_context_QueryInterface(ID3D11Devic { *out = &context->ID3D11DeviceContext1_iface; } - else if (IsEqualGUID(iid, &IID_ID3D11Multithread)) + else if (context->type == D3D11_DEVICE_CONTEXT_IMMEDIATE && IsEqualGUID(iid, &IID_ID3D11Multithread)) { *out = &context->ID3D11Multithread_iface; } @@ -390,6 +390,11 @@ static ULONG STDMETHODCALLTYPE d3d11_device_context_Release(ID3D11DeviceContext1
if (!refcount) { + if (context->type != D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + wined3d_deferred_context_destroy(context->wined3d_context); + heap_free(context); + } ID3D11Device2_Release(&context->device->ID3D11Device2_iface); }
@@ -2645,9 +2650,11 @@ static void STDMETHODCALLTYPE d3d11_device_context_Flush(ID3D11DeviceContext1 *i
static D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE d3d11_device_context_GetType(ID3D11DeviceContext1 *iface) { + struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + TRACE("iface %p.\n", iface);
- return D3D11_DEVICE_CONTEXT_IMMEDIATE; + return context->type; }
static UINT STDMETHODCALLTYPE d3d11_device_context_GetContextFlags(ID3D11DeviceContext1 *iface) @@ -2826,13 +2833,18 @@ static void STDMETHODCALLTYPE d3d11_device_context_SwapDeviceContextState(ID3D11
TRACE("iface %p, state %p, prev %p.\n", iface, state, prev);
- if (!state) + if (prev) + *prev = NULL; + + if (context->type != D3D11_DEVICE_CONTEXT_IMMEDIATE) { - if (prev) - *prev = NULL; + WARN("SwapDeviceContextState is not allowed on a deferred context.\n"); return; }
+ if (!state) + return; + wined3d_mutex_lock();
prev_impl = device->state; @@ -3082,11 +3094,13 @@ static const struct ID3D11MultithreadVtbl d3d11_multithread_vtbl = d3d11_multithread_GetMultithreadProtected, };
-static void d3d11_device_context_init(struct d3d11_device_context *context, struct d3d_device *device) +static void d3d11_device_context_init(struct d3d11_device_context *context, struct d3d_device *device, + D3D11_DEVICE_CONTEXT_TYPE type) { context->ID3D11DeviceContext1_iface.lpVtbl = &d3d11_device_context_vtbl; context->ID3D11Multithread_iface.lpVtbl = &d3d11_multithread_vtbl; context->refcount = 1; + context->type = type;
context->device = device; ID3D11Device2_AddRef(&device->ID3D11Device2_iface); @@ -3575,13 +3589,49 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateCounter(ID3D11Device2 *iface return E_NOTIMPL; }
+static HRESULT d3d11_deferred_context_create(struct d3d_device *device, + UINT flags, struct d3d11_device_context **context) +{ + struct d3d11_device_context *object; + HRESULT hr; + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + d3d11_device_context_init(object, device, D3D11_DEVICE_CONTEXT_DEFERRED); + + wined3d_mutex_lock(); + if (FAILED(hr = wined3d_deferred_context_create(device->wined3d_device, &object->wined3d_context))) + { + WARN("Failed to create wined3d deferred context, hr %#x.\n", hr); + heap_free(object); + wined3d_mutex_unlock(); + return hr; + } + wined3d_mutex_unlock(); + + TRACE("Created deferred context %p.\n", object); + *context = object; + + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext(ID3D11Device2 *iface, UINT flags, ID3D11DeviceContext **context) { - FIXME("iface %p, flags %#x, context %p stub!\n", iface, flags, context); + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_device_context *object; + HRESULT hr;
- *context = NULL; - return E_NOTIMPL; + TRACE("iface %p, flags %#x, context %p.\n", iface, flags, context); + + if (FAILED(hr = d3d11_deferred_context_create(device, flags, &object))) + return hr; + + *context = (ID3D11DeviceContext *)&object->ID3D11DeviceContext1_iface; + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResource(ID3D11Device2 *iface, HANDLE resource, REFIID iid, @@ -6655,7 +6705,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown) device->d3d11_only = FALSE; device->state = NULL;
- d3d11_device_context_init(&device->immediate_context, device); + d3d11_device_context_init(&device->immediate_context, device, D3D11_DEVICE_CONTEXT_IMMEDIATE); ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface);
wine_rb_init(&device->blend_states, d3d_blend_state_compare); diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 089755fd1ba..f415cbaad45 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -2266,6 +2266,8 @@ static void test_create_deferred_context(void)
hr = ID3D11Device_CreateDeferredContext(device, 0, &context); todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Failed to create deferred context, hr %#x.\n", hr); + if (hr == S_OK) + ID3D11DeviceContext_Release(context);
refcount = ID3D11Device_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); @@ -2278,9 +2280,7 @@ static void test_create_deferred_context(void)
expected_refcount = get_refcount(device) + 1; hr = ID3D11Device_CreateDeferredContext(device, 0, &context); - todo_wine ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); - if (FAILED(hr)) - goto done; + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); refcount = get_refcount(device); ok(refcount == expected_refcount, "Got refcount %u, expected %u.\n", refcount, expected_refcount); refcount = get_refcount(context); @@ -2294,7 +2294,6 @@ static void test_create_deferred_context(void) refcount = ID3D11DeviceContext_Release(context); ok(!refcount, "Got unexpected refcount %u.\n", refcount);
-done: refcount = ID3D11Device_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); } @@ -32270,14 +32269,7 @@ static void test_deferred_context_state(void) ID3D11DeviceContext_PSSetConstantBuffers(immediate, 0, 1, &green_buffer);
hr = ID3D11Device_CreateDeferredContext(device, 0, &deferred); - todo_wine ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); - if (hr != S_OK) - { - ID3D11Buffer_Release(blue_buffer); - ID3D11Buffer_Release(green_buffer); - release_test_context(&test_context); - return; - } + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr);
ID3D11DeviceContext_PSGetConstantBuffers(deferred, 0, 1, &ret_buffer); ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer); @@ -32289,7 +32281,15 @@ static void test_deferred_context_state(void) ID3D11Buffer_Release(ret_buffer);
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list1); - ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + todo_wine ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + if (hr != S_OK) + { + ID3D11DeviceContext_Release(deferred); + ID3D11Buffer_Release(blue_buffer); + ID3D11Buffer_Release(green_buffer); + release_test_context(&test_context); + return; + }
ID3D11DeviceContext_PSGetConstantBuffers(deferred, 0, 1, &ret_buffer); ok(ret_buffer == blue_buffer, "Got unexpected buffer %p.\n", ret_buffer); @@ -32468,12 +32468,7 @@ static void test_deferred_context_rendering(void) immediate = test_context.immediate_context;
hr = ID3D11Device_CreateDeferredContext(device, 0, &deferred); - todo_wine ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); - if (hr != S_OK) - { - release_test_context(&test_context); - return; - } + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr);
memset(&blend_desc, 0, sizeof(blend_desc));
@@ -32492,7 +32487,16 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(deferred, test_context.backbuffer_rtv, green);
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list1); - ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + todo_wine ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); + if (hr != S_OK) + { + ID3D11BlendState_Release(red_blend); + ID3D11BlendState_Release(green_blend); + ID3D11BlendState_Release(blue_blend); + ID3D11DeviceContext_Release(deferred); + release_test_context(&test_context); + return; + }
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list2); ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); @@ -32729,12 +32733,7 @@ static void test_deferred_context_map(void) immediate = test_context.immediate_context;
hr = ID3D11Device_CreateDeferredContext(device, 0, &deferred); - todo_wine ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); - if (hr != S_OK) - { - release_test_context(&test_context); - return; - } + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(data); ++i) data[i] = i; @@ -32758,13 +32757,21 @@ static void test_deferred_context_map(void) ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE, 0, &map_desc); - ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map_desc); - ok(hr == D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD, "Got unexpected hr %#x.\n", hr);
hr = ID3D11DeviceContext_Map(deferred, (ID3D11Resource *)buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map_desc); - ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + if (hr != S_OK) + { + ID3D11Buffer_Release(buffer2); + ID3D11Buffer_Release(buffer); + ID3D11DeviceContext_Release(deferred); + release_test_context(&test_context); + return; + } map_data = map_desc.pData; /* The previous contents of map_data are undefined and may in practice be * uninitialized garbage. */ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 8702ac08631..3f05d593b7c 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3162,3 +3162,149 @@ void wined3d_cs_destroy(struct wined3d_cs *cs) heap_free(cs->data); heap_free(cs); } + +struct wined3d_deferred_context +{ + struct wined3d_device_context c; + + SIZE_T data_size, data_capacity; + void *data; +}; + +static struct wined3d_deferred_context *wined3d_deferred_context_from_context(struct wined3d_device_context *context) +{ + return CONTAINING_RECORD(context, struct wined3d_deferred_context, c); +} + +static void *wined3d_deferred_context_require_space(struct wined3d_device_context *context, + size_t size, enum wined3d_cs_queue_id queue_id) +{ + struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + struct wined3d_cs_packet *packet; + size_t header_size, packet_size; + + assert(queue_id == WINED3D_CS_QUEUE_DEFAULT); + + header_size = offsetof(struct wined3d_cs_packet, data[0]); + packet_size = offsetof(struct wined3d_cs_packet, data[size]); + packet_size = (packet_size + header_size - 1) & ~(header_size - 1); + + if (!wined3d_array_reserve(&deferred->data, &deferred->data_capacity, deferred->data_size + packet_size, 1)) + return NULL; + + packet = (struct wined3d_cs_packet *)((BYTE *)deferred->data + deferred->data_size); + TRACE("size was %zu, adding %zu\n", (size_t)deferred->data_size, packet_size); + deferred->data_size += packet_size; + packet->size = packet_size - header_size; + return &packet->data; +} + +static void wined3d_deferred_context_submit(struct wined3d_device_context *context, enum wined3d_cs_queue_id queue_id) +{ + assert(queue_id == WINED3D_CS_QUEUE_DEFAULT); + + /* Nothing to do. */ +} + +static void wined3d_deferred_context_finish(struct wined3d_device_context *context, enum wined3d_cs_queue_id queue_id) +{ + /* This should not happen; we cannot meaningfully finish a deferred context. */ + ERR("Ignoring finish() on a deferred context.\n"); +} + +static void wined3d_deferred_context_push_constants(struct wined3d_device_context *context, + enum wined3d_push_constants p, unsigned int start_idx, unsigned int count, const void *constants) +{ + FIXME("context %p, p %#x, start_idx %u, count %u, constants %p, stub!\n", context, p, start_idx, count, constants); +} + +static HRESULT wined3d_deferred_context_map(struct wined3d_device_context *context, + struct wined3d_resource *resource, unsigned int sub_resource_idx, + struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags) +{ + FIXME("context %p, resource %p, sub_resource_idx %u, map_desc %p, box %p, flags %#x, stub!\n", + context, resource, sub_resource_idx, map_desc, box, flags); + return E_NOTIMPL; +} + +static HRESULT wined3d_deferred_context_unmap(struct wined3d_device_context *context, + struct wined3d_resource *resource, unsigned int sub_resource_idx) +{ + FIXME("context %p, resource %p, sub_resource_idx %u, stub!\n", context, resource, sub_resource_idx); + return E_NOTIMPL; +} + +static void wined3d_deferred_context_update_sub_resource(struct wined3d_device_context *context, + struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, + const void *data, unsigned int row_pitch, unsigned int slice_pitch) +{ + FIXME("context %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, slice_pitch %u, stub!\n", + context, resource, sub_resource_idx, debug_box(box), data, row_pitch, slice_pitch); +} + +static void wined3d_deferred_context_issue_query(struct wined3d_device_context *context, + struct wined3d_query *query, unsigned int flags) +{ + FIXME("context %p, query %p, flags %#x, stub!\n", context, query, flags); +} + +static void wined3d_deferred_context_flush(struct wined3d_device_context *context) +{ + FIXME("context %p, stub!\n", context); +} + +static void wined3d_deferred_context_acquire_resource(struct wined3d_device_context *context, + struct wined3d_resource *resource) +{ + FIXME("context %p, resource %p, stub!\n", context, resource); +} + +static const struct wined3d_device_context_ops wined3d_deferred_context_ops = +{ + wined3d_deferred_context_require_space, + wined3d_deferred_context_submit, + wined3d_deferred_context_finish, + wined3d_deferred_context_push_constants, + wined3d_deferred_context_map, + wined3d_deferred_context_unmap, + wined3d_deferred_context_update_sub_resource, + wined3d_deferred_context_issue_query, + wined3d_deferred_context_flush, + wined3d_deferred_context_acquire_resource, +}; + +HRESULT CDECL wined3d_deferred_context_create(struct wined3d_device *device, struct wined3d_device_context **context) +{ + struct wined3d_deferred_context *object; + HRESULT hr; + + TRACE("device %p, context %p.\n", device, context); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_state_create(device, &device->cs->c.state->feature_level, 1, &object->c.state))) + { + heap_free(object); + return hr; + } + + object->c.ops = &wined3d_deferred_context_ops; + object->c.device = device; + + TRACE("Created deferred context %p.\n", object); + *context = &object->c; + + return S_OK; +} + +void CDECL wined3d_deferred_context_destroy(struct wined3d_device_context *context) +{ + struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + + TRACE("context %p.\n", context); + + wined3d_state_destroy(deferred->c.state); + heap_free(deferred->data); + heap_free(deferred); +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 9f3dfed7ef8..901e9bee621 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -33,6 +33,9 @@ @ cdecl wined3d_buffer_get_resource(ptr) @ cdecl wined3d_buffer_incref(ptr)
+@ cdecl wined3d_deferred_context_create(ptr ptr) +@ cdecl wined3d_deferred_context_destroy(ptr) + @ cdecl wined3d_depth_stencil_state_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_depth_stencil_state_decref(ptr) @ cdecl wined3d_depth_stencil_state_get_parent(ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 2ee18bcaaed..0be192b0f01 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2340,6 +2340,9 @@ void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer); struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer); ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
+HRESULT __cdecl wined3d_deferred_context_create(struct wined3d_device *device, struct wined3d_device_context **context); +void __cdecl wined3d_deferred_context_destroy(struct wined3d_device_context *context); + HRESULT __cdecl wined3d_depth_stencil_state_create(struct wined3d_device *device, const struct wined3d_depth_stencil_state_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_depth_stencil_state **state);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 169 ++++++++++++--------------------- dlls/wined3d/cs.c | 53 ++++++----- dlls/wined3d/device.c | 71 ++++++++------ dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 6 +- include/wine/wined3d.h | 5 +- 6 files changed, 141 insertions(+), 165 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 0ba195b73eb..bfb21b59839 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -578,6 +578,32 @@ static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *ifac wined3d_mutex_unlock(); }
+static void d3d11_device_context_set_shader_resource_views(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int count, ID3D11ShaderResourceView *const *views) +{ + struct wined3d_shader_resource_view *wined3d_views[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + unsigned int i; + + if (count > ARRAY_SIZE(wined3d_views)) + { + WARN("View count %u exceeds limit; ignoring call.\n", count); + return; + } + + for (i = 0; i < count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); + + wined3d_views[i] = view ? view->wined3d_view : NULL; + } + + wined3d_mutex_lock(); + wined3d_device_context_set_shader_resource_views(context->wined3d_context, + type, start_slot, count, wined3d_views); + wined3d_mutex_unlock(); +} + static void STDMETHODCALLTYPE d3d11_device_context_GetDevice(ID3D11DeviceContext1 *iface, ID3D11Device **device) { struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); @@ -631,21 +657,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_VSSetConstantBuffers(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_PSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_PIXEL, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_PSSetShader(ID3D11DeviceContext1 *iface, @@ -913,20 +928,9 @@ static void STDMETHODCALLTYPE d3d11_device_context_IASetPrimitiveTopology(ID3D11 static void STDMETHODCALLTYPE d3d11_device_context_VSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_VERTEX, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_VSSetSamplers(ID3D11DeviceContext1 *iface, @@ -1025,20 +1029,9 @@ static void STDMETHODCALLTYPE d3d11_device_context_SetPredication(ID3D11DeviceCo static void STDMETHODCALLTYPE d3d11_device_context_GSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_GEOMETRY, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_GSSetSamplers(ID3D11DeviceContext1 *iface, @@ -1543,21 +1536,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_ExecuteCommandList(ID3D11Devi static void STDMETHODCALLTYPE d3d11_device_context_HSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_HULL, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_HULL, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_HSSetShader(ID3D11DeviceContext1 *iface, @@ -1611,21 +1593,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_HSSetConstantBuffers(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_DSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_DOMAIN, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_DSSetShader(ID3D11DeviceContext1 *iface, @@ -1679,21 +1650,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_DSSetConstantBuffers(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_CSSetShaderResources(ID3D11DeviceContext1 *iface, UINT start_slot, UINT view_count, ID3D11ShaderResourceView *const *views) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D11ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(context->wined3d_context, WINED3D_SHADER_TYPE_COMPUTE, - start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d11_device_context_CSSetUnorderedAccessViews(ID3D11DeviceContext1 *iface, @@ -4589,6 +4549,32 @@ static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, enum wined3d wined3d_mutex_unlock(); }
+static void d3d10_device_set_shader_resource_views(ID3D10Device1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int count, ID3D10ShaderResourceView *const *views) +{ + struct wined3d_shader_resource_view *wined3d_views[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + if (count > ARRAY_SIZE(wined3d_views)) + { + WARN("View count %u exceeds limit; ignoring call.\n", count); + return; + } + + for (i = 0; i < count; ++i) + { + struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); + + wined3d_views[i] = view ? view->wined3d_view : NULL; + } + + wined3d_mutex_lock(); + wined3d_device_context_set_shader_resource_views(device->immediate_context.wined3d_context, + type, start_slot, count, wined3d_views); + wined3d_mutex_unlock(); +} + static void STDMETHODCALLTYPE d3d10_device_VSSetConstantBuffers(ID3D10Device1 *iface, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) { @@ -4602,21 +4588,10 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetConstantBuffers(ID3D10Device1 *i static void STDMETHODCALLTYPE d3d10_device_PSSetShaderResources(ID3D10Device1 *iface, UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, - WINED3D_SHADER_TYPE_PIXEL, start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d10_device_PSSetShader(ID3D10Device1 *iface, @@ -4826,21 +4801,10 @@ static void STDMETHODCALLTYPE d3d10_device_IASetPrimitiveTopology(ID3D10Device1 static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device1 *iface, UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, - WINED3D_SHADER_TYPE_VERTEX, start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d10_device_VSSetSamplers(ID3D10Device1 *iface, @@ -4880,21 +4844,10 @@ static void STDMETHODCALLTYPE d3d10_device_SetPredication(ID3D10Device1 *iface, static void STDMETHODCALLTYPE d3d10_device_GSSetShaderResources(ID3D10Device1 *iface, UINT start_slot, UINT view_count, ID3D10ShaderResourceView *const *views) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
- wined3d_mutex_lock(); - for (i = 0; i < view_count; ++i) - { - struct d3d_shader_resource_view *view = unsafe_impl_from_ID3D10ShaderResourceView(views[i]); - - wined3d_device_context_set_shader_resource_view(device->immediate_context.wined3d_context, - WINED3D_SHADER_TYPE_GEOMETRY, start_slot + i, view ? view->wined3d_view : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_shader_resource_views(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, view_count, views); }
static void STDMETHODCALLTYPE d3d10_device_GSSetSamplers(ID3D10Device1 *iface, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 712a20696a4..12d3c99e909 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -118,7 +118,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_TEXTURE, - WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW, + WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS, WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SHADER, @@ -307,12 +307,13 @@ struct wined3d_cs_set_color_key struct wined3d_color_key color_key; };
-struct wined3d_cs_set_shader_resource_view +struct wined3d_cs_set_shader_resource_views { enum wined3d_cs_op opcode; enum wined3d_shader_type type; - UINT view_idx; - struct wined3d_shader_resource_view *view; + unsigned int start_idx; + unsigned int count; + struct wined3d_shader_resource_view *views[1]; };
struct wined3d_cs_set_unordered_access_view @@ -606,7 +607,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); - WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS); WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); @@ -1665,18 +1666,23 @@ void wined3d_device_context_emit_set_texture(struct wined3d_device_context *cont wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_shader_resource_views(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_shader_resource_view *op = data; - struct wined3d_shader_resource_view *prev; + const struct wined3d_cs_set_shader_resource_views *op = data; + unsigned int i;
- prev = cs->state.shader_resource_view[op->type][op->view_idx]; - cs->state.shader_resource_view[op->type][op->view_idx] = op->view; + for (i = 0; i < op->count; ++i) + { + struct wined3d_shader_resource_view *prev = cs->state.shader_resource_view[op->type][op->start_idx + i]; + struct wined3d_shader_resource_view *view = op->views[i];
- if (op->view) - InterlockedIncrement(&op->view->resource->bind_count); - if (prev) - InterlockedDecrement(&prev->resource->bind_count); + cs->state.shader_resource_view[op->type][op->start_idx + i] = view; + + if (view) + InterlockedIncrement(&view->resource->bind_count); + if (prev) + InterlockedDecrement(&prev->resource->bind_count); + }
if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); @@ -1684,16 +1690,19 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons device_invalidate_state(cs->c.device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); }
-void wined3d_device_context_emit_set_shader_resource_view(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int view_idx, struct wined3d_shader_resource_view *view) +void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_shader_resource_view *const *views) { - struct wined3d_cs_set_shader_resource_view *op; + struct wined3d_cs_set_shader_resource_views *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_shader_resource_views, views[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS; op->type = type; - op->view_idx = view_idx; - op->view = view; + op->start_idx = start_idx; + op->count = count; + memcpy(op->views, views, count * sizeof(*views));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2922,7 +2931,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, - /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, + /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS */ wined3d_cs_exec_set_shader_resource_views, /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index f0aa9fbd250..a90c55bb6d6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1701,10 +1701,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte { wined3d_device_context_emit_set_sampler(context, i, j, state->sampler[i][j]); } - for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j) - { - wined3d_device_context_emit_set_shader_resource_view(context, i, j, state->shader_resource_view[i][j]); - } + wined3d_device_context_emit_set_shader_resource_views(context, i, 0, + MAX_SHADER_RESOURCE_VIEWS, state->shader_resource_view[i]); }
for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i) @@ -1980,45 +1978,58 @@ void CDECL wined3d_device_context_set_scissor_rects(struct wined3d_device_contex wined3d_device_context_emit_set_scissor_rects(context, rect_count, rects); }
-void CDECL wined3d_device_context_set_shader_resource_view(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_shader_resource_view *view) +void CDECL wined3d_device_context_set_shader_resource_views(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_shader_resource_view *const *const views) { + struct wined3d_shader_resource_view *real_views[MAX_SHADER_RESOURCE_VIEWS]; struct wined3d_state *state = context->state; - const struct wined3d_rendertarget_view *dsv; - struct wined3d_shader_resource_view *prev; + const struct wined3d_rendertarget_view *dsv = state->fb.depth_stencil; + unsigned int i;
- TRACE("context %p, type %#x, idx %u, view %p.\n", context, type, idx, view); + TRACE("context %p, type %#x, start_idx %u, count %u, views %p.\n", context, type, start_idx, count, views);
- if (idx >= MAX_SHADER_RESOURCE_VIEWS) + if (start_idx + count > MAX_SHADER_RESOURCE_VIEWS) { - WARN("Invalid view index %u.\n", idx); + WARN("Invalid view index %u, count %u.\n", start_idx, count); return; }
- prev = state->shader_resource_view[type][idx]; - if (view == prev) + if (!memcmp(views, &state->shader_resource_view[type][start_idx], count * sizeof(*views))) return;
- if (view && (wined3d_is_srv_rtv_bound(state, view) - || ((dsv = state->fb.depth_stencil) - && dsv->resource == view->resource && wined3d_dsv_srv_conflict(dsv, view->format)))) + memcpy(real_views, views, count * sizeof(*views)); + + for (i = 0; i < count; ++i) { - WARN("Application is trying to bind resource which is attached as render target.\n"); - view = NULL; + struct wined3d_shader_resource_view *view = real_views[i]; + + if (view && (wined3d_is_srv_rtv_bound(state, view) + || (dsv && dsv->resource == view->resource && wined3d_dsv_srv_conflict(dsv, view->format)))) + { + WARN("Application is trying to bind resource which is attached as render target.\n"); + real_views[i] = NULL; + } }
- if (view) + wined3d_device_context_emit_set_shader_resource_views(context, type, start_idx, count, real_views); + for (i = 0; i < count; ++i) { - wined3d_shader_resource_view_incref(view); - wined3d_srv_bind_count_inc(view); - } + struct wined3d_shader_resource_view *prev = state->shader_resource_view[type][start_idx + i]; + struct wined3d_shader_resource_view *view = real_views[i];
- state->shader_resource_view[type][idx] = view; - wined3d_device_context_emit_set_shader_resource_view(context, type, idx, view); - if (prev) - { - wined3d_srv_bind_count_dec(prev); - wined3d_shader_resource_view_decref(prev); + if (view) + { + wined3d_shader_resource_view_incref(view); + wined3d_srv_bind_count_inc(view); + } + + state->shader_resource_view[type][start_idx + i] = view; + if (prev) + { + wined3d_srv_bind_count_dec(prev); + wined3d_shader_resource_view_decref(prev); + } } }
@@ -2098,8 +2109,10 @@ static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_cont && ((!dsv && wined3d_is_srv_rtv_bound(state, srv)) || (dsv && wined3d_dsv_srv_conflict(view, srv->format)))) { + static struct wined3d_shader_resource_view *const null_srv; + WARN("Application sets bound resource as render target.\n"); - wined3d_device_context_set_shader_resource_view(context, i, j, NULL); + wined3d_device_context_set_shader_resource_views(context, i, j, 1, &null_srv); } } } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 3f22af60689..2c61996be6d 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -133,7 +133,7 @@ @ cdecl wined3d_device_context_set_sampler(ptr long long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr) -@ cdecl wined3d_device_context_set_shader_resource_view(ptr long long ptr) +@ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr) @ cdecl wined3d_device_context_set_state(ptr ptr) @ cdecl wined3d_device_context_set_stream_output(ptr long ptr long) @ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index afdea25ded9..ff10b1362f9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4821,9 +4821,9 @@ void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type, struct wined3d_shader *shader) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_shader_resource_view(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int view_idx, - struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_shader_resource_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 2e01d27ed68..7272a40287e 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2517,8 +2517,9 @@ void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_cont const RECT *rects); void __cdecl wined3d_device_context_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type, struct wined3d_shader *shader); -void __cdecl wined3d_device_context_set_shader_resource_view(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_shader_resource_view *view); +void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_device_context *context, + enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, + struct wined3d_shader_resource_view *const *views); void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state); void __cdecl wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx, struct wined3d_buffer *buffer, unsigned int offset);
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=41636 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 12 ++++++++++-- dlls/d3d11/tests/d3d11.c | 5 +---- 2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 459c49145cd..39144df3dc4 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -4077,9 +4077,17 @@ static void STDMETHODCALLTYPE d3d11_device_GetImmediateContext1(ID3D11Device2 *i static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeferredContext1(ID3D11Device2 *iface, UINT flags, ID3D11DeviceContext1 **context) { - FIXME("iface %p, flags %#x, context %p stub!\n", iface, flags, context); + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d11_device_context *object; + HRESULT hr;
- return E_NOTIMPL; + TRACE("iface %p, flags %#x, context %p.\n", iface, flags, context); + + if (FAILED(hr = d3d11_deferred_context_create(device, flags, &object))) + return hr; + + *context = &object->ID3D11DeviceContext1_iface; + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d11_device_CreateBlendState1(ID3D11Device2 *iface, diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index f415cbaad45..d799bed25f4 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -32410,9 +32410,7 @@ static void test_deferred_context_swap_state(void) ID3D11DeviceContext1_PSSetConstantBuffers(immediate, 0, 1, &green_buffer);
hr = ID3D11Device1_CreateDeferredContext1(device, 0, &deferred); - todo_wine ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr); - if (hr != S_OK) - goto out; + ok(hr == S_OK, "Failed to create deferred context, hr %#x.\n", hr);
feature_level = ID3D11Device1_GetFeatureLevel(device); hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION, @@ -32433,7 +32431,6 @@ static void test_deferred_context_swap_state(void) ID3DDeviceContextState_Release(state); ID3D11DeviceContext1_Release(deferred);
-out: ID3D11Buffer_Release(green_buffer); ID3D11DeviceContext1_Release(immediate); ID3D11Device1_Release(device);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 168 ++++++++++++--------------------- dlls/wined3d/cs.c | 38 ++++---- dlls/wined3d/device.c | 38 ++++---- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +- include/wine/wined3d.h | 4 +- 6 files changed, 107 insertions(+), 147 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index bfb21b59839..b3b56af4941 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -604,6 +604,31 @@ static void d3d11_device_context_set_shader_resource_views(ID3D11DeviceContext1 wined3d_mutex_unlock(); }
+static void d3d11_device_context_set_samplers(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int count, ID3D11SamplerState *const *samplers) +{ + struct wined3d_sampler *wined3d_samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + unsigned int i; + + if (count > ARRAY_SIZE(wined3d_samplers)) + { + WARN("Sampler count %u exceeds limit; ignoring call.\n", count); + return; + } + + for (i = 0; i < count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); + + wined3d_samplers[i] = sampler ? sampler->wined3d_sampler : NULL; + } + + wined3d_mutex_lock(); + wined3d_device_context_set_samplers(context->wined3d_context, type, start_slot, count, wined3d_samplers); + wined3d_mutex_unlock(); +} + static void STDMETHODCALLTYPE d3d11_device_context_GetDevice(ID3D11DeviceContext1 *iface, ID3D11Device **device) { struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); @@ -684,21 +709,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_PSSetShader(ID3D11DeviceConte static void STDMETHODCALLTYPE d3d11_device_context_PSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_PIXEL, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_VSSetShader(ID3D11DeviceContext1 *iface, @@ -936,21 +950,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_VSSetShaderResources(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_VSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_VERTEX, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_Begin(ID3D11DeviceContext1 *iface, @@ -1037,21 +1040,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_GSSetShaderResources(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_GSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_GEOMETRY, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargets(ID3D11DeviceContext1 *iface, @@ -1563,21 +1555,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_HSSetShader(ID3D11DeviceConte static void STDMETHODCALLTYPE d3d11_device_context_HSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_HULL, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_HSSetConstantBuffers(ID3D11DeviceContext1 *iface, @@ -1620,21 +1601,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_DSSetShader(ID3D11DeviceConte static void STDMETHODCALLTYPE d3d11_device_context_DSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_DOMAIN, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_DSSetConstantBuffers(ID3D11DeviceContext1 *iface, @@ -1697,21 +1667,10 @@ static void STDMETHODCALLTYPE d3d11_device_context_CSSetShader(ID3D11DeviceConte static void STDMETHODCALLTYPE d3d11_device_context_CSSetSamplers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT sampler_count, ID3D11SamplerState *const *samplers) { - struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D11SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(context->wined3d_context, WINED3D_SHADER_TYPE_COMPUTE, start_slot + i, - sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d11_device_context_set_samplers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d11_device_context_CSSetConstantBuffers(ID3D11DeviceContext1 *iface, @@ -4575,6 +4534,32 @@ static void d3d10_device_set_shader_resource_views(ID3D10Device1 *iface, enum wi wined3d_mutex_unlock(); }
+static void d3d10_device_set_samplers(ID3D10Device1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int count, ID3D10SamplerState *const *samplers) +{ + struct wined3d_sampler *wined3d_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT]; + struct d3d_device *device = impl_from_ID3D10Device(iface); + unsigned int i; + + if (count > ARRAY_SIZE(wined3d_samplers)) + { + WARN("Sampler count %u exceeds limit; ignoring call.\n", count); + return; + } + + for (i = 0; i < count; ++i) + { + struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); + + wined3d_samplers[i] = sampler ? sampler->wined3d_sampler : NULL; + } + + wined3d_mutex_lock(); + wined3d_device_context_set_samplers(device->immediate_context.wined3d_context, + type, start_slot, count, wined3d_samplers); + wined3d_mutex_unlock(); +} + static void STDMETHODCALLTYPE d3d10_device_VSSetConstantBuffers(ID3D10Device1 *iface, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) { @@ -4611,21 +4596,10 @@ static void STDMETHODCALLTYPE d3d10_device_PSSetShader(ID3D10Device1 *iface, static void STDMETHODCALLTYPE d3d10_device_PSSetSamplers(ID3D10Device1 *iface, UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, - WINED3D_SHADER_TYPE_PIXEL, start_slot + i, sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_samplers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d10_device_VSSetShader(ID3D10Device1 *iface, @@ -4810,21 +4784,10 @@ static void STDMETHODCALLTYPE d3d10_device_VSSetShaderResources(ID3D10Device1 *i static void STDMETHODCALLTYPE d3d10_device_VSSetSamplers(ID3D10Device1 *iface, UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, - WINED3D_SHADER_TYPE_VERTEX, start_slot + i, sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_samplers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d10_device_SetPredication(ID3D10Device1 *iface, ID3D10Predicate *predicate, BOOL value) @@ -4853,21 +4816,10 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetShaderResources(ID3D10Device1 *i static void STDMETHODCALLTYPE d3d10_device_GSSetSamplers(ID3D10Device1 *iface, UINT start_slot, UINT sampler_count, ID3D10SamplerState *const *samplers) { - struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int i; - TRACE("iface %p, start_slot %u, sampler_count %u, samplers %p.\n", iface, start_slot, sampler_count, samplers);
- wined3d_mutex_lock(); - for (i = 0; i < sampler_count; ++i) - { - struct d3d_sampler_state *sampler = unsafe_impl_from_ID3D10SamplerState(samplers[i]); - - wined3d_device_context_set_sampler(device->immediate_context.wined3d_context, WINED3D_SHADER_TYPE_GEOMETRY, - start_slot + i, sampler ? sampler->wined3d_sampler : NULL); - } - wined3d_mutex_unlock(); + d3d10_device_set_samplers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, sampler_count, samplers); }
static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *iface, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 12d3c99e909..83c9cef5c06 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -120,7 +120,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_TEXTURE, WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS, WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, - WINED3D_CS_OP_SET_SAMPLER, + WINED3D_CS_OP_SET_SAMPLERS, WINED3D_CS_OP_SET_SHADER, WINED3D_CS_OP_SET_BLEND_STATE, WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE, @@ -325,12 +325,13 @@ struct wined3d_cs_set_unordered_access_view unsigned int initial_count; };
-struct wined3d_cs_set_sampler +struct wined3d_cs_set_samplers { enum wined3d_cs_op opcode; enum wined3d_shader_type type; - UINT sampler_idx; - struct wined3d_sampler *sampler; + unsigned int start_idx; + unsigned int count; + struct wined3d_sampler *samplers[1]; };
struct wined3d_cs_set_shader @@ -609,7 +610,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS); WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); - WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER); + WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); WINED3D_TO_STR(WINED3D_CS_OP_SET_BLEND_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE); @@ -1742,27 +1743,32 @@ void wined3d_device_context_emit_set_unordered_access_view(struct wined3d_device wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_samplers(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_sampler *op = data; + const struct wined3d_cs_set_samplers *op = data; + unsigned int i; + + for (i = 0; i < op->count; ++i) + cs->state.sampler[op->type][op->start_idx + i] = op->samplers[i];
- cs->state.sampler[op->type][op->sampler_idx] = op->sampler; if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); else device_invalidate_state(cs->c.device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); }
-void wined3d_device_context_emit_set_sampler(struct wined3d_device_context *context, enum wined3d_shader_type type, - unsigned int sampler_idx, struct wined3d_sampler *sampler) +void wined3d_device_context_emit_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, + unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) { - struct wined3d_cs_set_sampler *op; + struct wined3d_cs_set_samplers *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_SAMPLER; + op = wined3d_device_context_require_space(context, offsetof(struct wined3d_cs_set_samplers, samplers[count]), + WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_SAMPLERS; op->type = type; - op->sampler_idx = sampler_idx; - op->sampler = sampler; + op->start_idx = start_idx; + op->count = count; + memcpy(op->samplers, samplers, count * sizeof(*samplers));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2933,7 +2939,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS */ wined3d_cs_exec_set_shader_resource_views, /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, - /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, + /* WINED3D_CS_OP_SET_SAMPLERS */ wined3d_cs_exec_set_samplers, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, /* WINED3D_CS_OP_SET_BLEND_STATE */ wined3d_cs_exec_set_blend_state, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_STATE */ wined3d_cs_exec_set_depth_stencil_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a90c55bb6d6..e478256ff5e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1697,10 +1697,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte { wined3d_device_context_emit_set_shader(context, i, state->shader[i]); wined3d_device_context_emit_set_constant_buffers(context, i, 0, MAX_CONSTANT_BUFFERS, state->cb[i]); - for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j) - { - wined3d_device_context_emit_set_sampler(context, i, j, state->sampler[i][j]); - } + wined3d_device_context_emit_set_samplers(context, i, 0, MAX_SAMPLER_OBJECTS, state->sampler[i]); wined3d_device_context_emit_set_shader_resource_views(context, i, 0, MAX_SHADER_RESOURCE_VIEWS, state->shader_resource_view[i]); } @@ -2033,30 +2030,35 @@ void CDECL wined3d_device_context_set_shader_resource_views(struct wined3d_devic } }
-void CDECL wined3d_device_context_set_sampler(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_sampler *sampler) +void CDECL wined3d_device_context_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, + unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) { struct wined3d_state *state = context->state; - struct wined3d_sampler *prev; + unsigned int i;
- TRACE("context %p, type %#x, idx %u, sampler %p.\n", context, type, idx, sampler); + TRACE("context %p, type %#x, start_idx %u, count %u, samplers %p.\n", context, type, start_idx, count, samplers);
- if (idx >= MAX_SAMPLER_OBJECTS) + if (start_idx + count > MAX_SAMPLER_OBJECTS) { - WARN("Invalid sampler index %u.\n", idx); + WARN("Invalid sampler index %u, count %u.\n", start_idx, count); return; }
- prev = state->sampler[type][idx]; - if (sampler == prev) + if (!memcmp(samplers, &state->sampler[type][start_idx], count * sizeof(*samplers))) return;
- if (sampler) - wined3d_sampler_incref(sampler); - state->sampler[type][idx] = sampler; - wined3d_device_context_emit_set_sampler(context, type, idx, sampler); - if (prev) - wined3d_sampler_decref(prev); + wined3d_device_context_emit_set_samplers(context, type, start_idx, count, samplers); + for (i = 0; i < count; ++i) + { + struct wined3d_sampler *prev = state->sampler[type][start_idx + i]; + struct wined3d_sampler *sampler = samplers[i]; + + if (sampler) + wined3d_sampler_incref(sampler); + state->sampler[type][start_idx + i] = sampler; + if (prev) + wined3d_sampler_decref(prev); + } }
void CDECL wined3d_device_context_set_unordered_access_view(struct wined3d_device_context *context, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 2c61996be6d..c93be0a1007 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -130,7 +130,7 @@ @ cdecl wined3d_device_context_set_primitive_type(ptr long long) @ cdecl wined3d_device_context_set_rasterizer_state(ptr ptr) @ cdecl wined3d_device_context_set_rendertarget_view(ptr long ptr long) -@ cdecl wined3d_device_context_set_sampler(ptr long long ptr) +@ cdecl wined3d_device_context_set_samplers(ptr long long long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr) @ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ff10b1362f9..75583c32f1c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4813,8 +4813,8 @@ void wined3d_device_context_emit_set_render_state(struct wined3d_device_context enum wined3d_render_state state, unsigned int value) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_sampler(struct wined3d_device_context *context, enum wined3d_shader_type type, - unsigned int sampler_idx, struct wined3d_sampler *sampler) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, + unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_sampler_state(struct wined3d_device_context *context, unsigned int sampler_idx, enum wined3d_sampler_state state, unsigned int value) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context *context, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 7272a40287e..5de5026107f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2511,8 +2511,8 @@ void __cdecl wined3d_device_context_set_rasterizer_state(struct wined3d_device_c struct wined3d_rasterizer_state *rasterizer_state); HRESULT __cdecl wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); -void __cdecl wined3d_device_context_set_sampler(struct wined3d_device_context *context, - enum wined3d_shader_type type, unsigned int idx, struct wined3d_sampler *sampler); +void __cdecl wined3d_device_context_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, + unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers); void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_context *context, unsigned int rect_count, const RECT *rects); void __cdecl wined3d_device_context_set_shader(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 3f05d593b7c..77d40801414 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3169,6 +3169,9 @@ struct wined3d_deferred_context
SIZE_T data_size, data_capacity; void *data; + + SIZE_T resource_count, resources_capacity; + struct wined3d_resource **resources; };
static struct wined3d_deferred_context *wined3d_deferred_context_from_context(struct wined3d_device_context *context) @@ -3256,7 +3259,14 @@ static void wined3d_deferred_context_flush(struct wined3d_device_context *contex static void wined3d_deferred_context_acquire_resource(struct wined3d_device_context *context, struct wined3d_resource *resource) { - FIXME("context %p, resource %p, stub!\n", context, resource); + struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + + if (!wined3d_array_reserve((void **)&deferred->resources, &deferred->resources_capacity, + deferred->resource_count + 1, sizeof(*deferred->resources))) + return; + + deferred->resources[deferred->resource_count++] = resource; + wined3d_resource_incref(resource); }
static const struct wined3d_device_context_ops wined3d_deferred_context_ops = @@ -3301,9 +3311,14 @@ HRESULT CDECL wined3d_deferred_context_create(struct wined3d_device *device, str void CDECL wined3d_deferred_context_destroy(struct wined3d_device_context *context) { struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + SIZE_T i;
TRACE("context %p.\n", context);
+ for (i = 0; i < deferred->resource_count; ++i) + wined3d_resource_decref(deferred->resources[i]); + heap_free(deferred->resources); + wined3d_state_destroy(deferred->c.state); heap_free(deferred->data); heap_free(deferred);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 46 +++++++++++++--------- dlls/wined3d/cs.c | 70 +++++++++++++++++++++------------- dlls/wined3d/device.c | 45 +++++++++++----------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 6 +-- include/wine/wined3d.h | 6 +-- 6 files changed, 102 insertions(+), 73 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index b3b56af4941..578e572797a 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1098,26 +1098,29 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargetsAndUnordere
if (unordered_access_view_count != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) { - wined3d_mutex_lock(); - for (i = 0; i < unordered_access_view_start_slot; ++i) + struct wined3d_unordered_access_view *wined3d_views[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0}; + unsigned int wined3d_initial_counts[D3D11_PS_CS_UAV_REGISTER_COUNT]; + + if (unordered_access_view_start_slot + unordered_access_view_count > ARRAY_SIZE(wined3d_views)) { - wined3d_device_context_set_unordered_access_view(context->wined3d_context, - WINED3D_PIPELINE_GRAPHICS, i, NULL, ~0u); + WARN("View count %u exceeds limit; ignoring call.\n", unordered_access_view_count); + return; } + + memset(wined3d_initial_counts, 0xff, sizeof(wined3d_initial_counts)); + for (i = 0; i < unordered_access_view_count; ++i) { - struct d3d11_unordered_access_view *view - = unsafe_impl_from_ID3D11UnorderedAccessView(unordered_access_views[i]); + struct d3d11_unordered_access_view *view = + unsafe_impl_from_ID3D11UnorderedAccessView(unordered_access_views[i]);
- wined3d_device_context_set_unordered_access_view(context->wined3d_context, - WINED3D_PIPELINE_GRAPHICS, unordered_access_view_start_slot + i, - view ? view->wined3d_view : NULL, initial_counts ? initial_counts[i] : ~0u); - } - for (; unordered_access_view_start_slot + i < D3D11_PS_CS_UAV_REGISTER_COUNT; ++i) - { - wined3d_device_context_set_unordered_access_view(context->wined3d_context, - WINED3D_PIPELINE_GRAPHICS, unordered_access_view_start_slot + i, NULL, ~0u); + wined3d_views[unordered_access_view_start_slot + i] = view ? view->wined3d_view : NULL; + wined3d_initial_counts[unordered_access_view_start_slot + i] = initial_counts ? initial_counts[i] : ~0u; } + + wined3d_mutex_lock(); + wined3d_device_context_set_unordered_access_views(context->wined3d_context, WINED3D_PIPELINE_GRAPHICS, + 0, ARRAY_SIZE(wined3d_views), wined3d_views, wined3d_initial_counts); wined3d_mutex_unlock(); } } @@ -1630,19 +1633,28 @@ static void STDMETHODCALLTYPE d3d11_device_context_CSSetUnorderedAccessViews(ID3 UINT start_slot, UINT view_count, ID3D11UnorderedAccessView *const *views, const UINT *initial_counts) { struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + struct wined3d_unordered_access_view *wined3d_views[D3D11_PS_CS_UAV_REGISTER_COUNT]; unsigned int i;
TRACE("iface %p, start_slot %u, view_count %u, views %p, initial_counts %p.\n", iface, start_slot, view_count, views, initial_counts);
- wined3d_mutex_lock(); + if (view_count > ARRAY_SIZE(wined3d_views)) + { + WARN("View count %u exceeds limit; ignoring call.\n", view_count); + return; + } + for (i = 0; i < view_count; ++i) { struct d3d11_unordered_access_view *view = unsafe_impl_from_ID3D11UnorderedAccessView(views[i]);
- wined3d_device_context_set_unordered_access_view(context->wined3d_context, WINED3D_PIPELINE_COMPUTE, - start_slot + i, view ? view->wined3d_view : NULL, initial_counts ? initial_counts[i] : ~0u); + wined3d_views[i] = view ? view->wined3d_view : NULL; } + + wined3d_mutex_lock(); + wined3d_device_context_set_unordered_access_views(context->wined3d_context, WINED3D_PIPELINE_COMPUTE, + start_slot, view_count, wined3d_views, initial_counts); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 83c9cef5c06..c3702ab1527 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -119,7 +119,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_TEXTURE, WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS, - WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, + WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEWS, WINED3D_CS_OP_SET_SAMPLERS, WINED3D_CS_OP_SET_SHADER, WINED3D_CS_OP_SET_BLEND_STATE, @@ -316,13 +316,17 @@ struct wined3d_cs_set_shader_resource_views struct wined3d_shader_resource_view *views[1]; };
-struct wined3d_cs_set_unordered_access_view +struct wined3d_cs_set_unordered_access_views { enum wined3d_cs_op opcode; enum wined3d_pipeline pipeline; - unsigned int view_idx; - struct wined3d_unordered_access_view *view; - unsigned int initial_count; + unsigned int start_idx; + unsigned int count; + struct + { + struct wined3d_unordered_access_view *view; + unsigned int initial_count; + } uavs[1]; };
struct wined3d_cs_set_samplers @@ -609,7 +613,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS); - WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEWS); WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); WINED3D_TO_STR(WINED3D_CS_OP_SET_BLEND_STATE); @@ -1708,37 +1712,49 @@ void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_unordered_access_views(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_unordered_access_view *op = data; - struct wined3d_unordered_access_view *prev; + const struct wined3d_cs_set_unordered_access_views *op = data; + unsigned int i;
- prev = cs->state.unordered_access_view[op->pipeline][op->view_idx]; - cs->state.unordered_access_view[op->pipeline][op->view_idx] = op->view; + for (i = 0; i < op->count; ++i) + { + struct wined3d_unordered_access_view *prev = cs->state.unordered_access_view[op->pipeline][op->start_idx + i]; + struct wined3d_unordered_access_view *view = op->uavs[i].view; + unsigned int initial_count = op->uavs[i].initial_count;
- if (op->view) - InterlockedIncrement(&op->view->resource->bind_count); - if (prev) - InterlockedDecrement(&prev->resource->bind_count); + cs->state.unordered_access_view[op->pipeline][op->start_idx + i] = view;
- if (op->view && op->initial_count != ~0u) - wined3d_unordered_access_view_set_counter(op->view, op->initial_count); + if (view) + InterlockedIncrement(&view->resource->bind_count); + if (prev) + InterlockedDecrement(&prev->resource->bind_count); + + if (view && initial_count != ~0u) + wined3d_unordered_access_view_set_counter(view, initial_count); + }
device_invalidate_state(cs->c.device, STATE_UNORDERED_ACCESS_VIEW_BINDING(op->pipeline)); }
-void wined3d_device_context_emit_set_unordered_access_view(struct wined3d_device_context *context, - enum wined3d_pipeline pipeline, unsigned int view_idx, struct wined3d_unordered_access_view *view, - unsigned int initial_count) +void wined3d_device_context_emit_set_unordered_access_views(struct wined3d_device_context *context, + enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, + struct wined3d_unordered_access_view *const *views, const unsigned int *initial_counts) { - struct wined3d_cs_set_unordered_access_view *op; + struct wined3d_cs_set_unordered_access_views *op; + unsigned int i;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_unordered_access_views, uavs[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEWS; op->pipeline = pipeline; - op->view_idx = view_idx; - op->view = view; - op->initial_count = initial_count; + op->start_idx = start_idx; + op->count = count; + for (i = 0; i < count; ++i) + { + op->uavs[i].view = views[i]; + op->uavs[i].initial_count = initial_counts ? initial_counts[i] : ~0u; + }
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2938,7 +2954,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS */ wined3d_cs_exec_set_shader_resource_views, - /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, + /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEWS */ wined3d_cs_exec_set_unordered_access_views, /* WINED3D_CS_OP_SET_SAMPLERS */ wined3d_cs_exec_set_samplers, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, /* WINED3D_CS_OP_SET_BLEND_STATE */ wined3d_cs_exec_set_blend_state, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e478256ff5e..faf11d25dcb 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1703,13 +1703,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte }
for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i) - { - for (j = 0; j < MAX_UNORDERED_ACCESS_VIEWS; ++j) - { - wined3d_device_context_emit_set_unordered_access_view(context, i, j, - state->unordered_access_view[i][j], ~0); - } - } + wined3d_device_context_emit_set_unordered_access_views(context, i, 0, MAX_UNORDERED_ACCESS_VIEWS, + state->unordered_access_view[i], NULL);
wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_VS_F, 0, WINED3D_MAX_VS_CONSTS_F, state->vs_consts_f); @@ -2061,31 +2056,37 @@ void CDECL wined3d_device_context_set_samplers(struct wined3d_device_context *co } }
-void CDECL wined3d_device_context_set_unordered_access_view(struct wined3d_device_context *context, - enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav, - unsigned int initial_count) +void CDECL wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, + enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, + struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts) { struct wined3d_state *state = context->state; - struct wined3d_unordered_access_view *prev; + unsigned int i;
- TRACE("context %p, pipeline %#x, idx %u, uav %p, initial_count %u.\n", context, pipeline, idx, uav, initial_count); + TRACE("context %p, pipeline %#x, start_idx %u, count %u, uavs %p, initial_counts %p.\n", + context, pipeline, start_idx, count, uavs, initial_counts);
- if (idx >= MAX_UNORDERED_ACCESS_VIEWS) + if (start_idx + count > MAX_UNORDERED_ACCESS_VIEWS) { - WARN("Invalid UAV index %u.\n", idx); + WARN("Invalid UAV index %u, count %u.\n", start_idx, count); return; }
- prev = state->unordered_access_view[pipeline][idx]; - if (uav == prev && initial_count == ~0u) + if (!memcmp(uavs, &state->unordered_access_view[pipeline][start_idx], count * sizeof(*uavs)) && !initial_counts) return;
- if (uav) - wined3d_unordered_access_view_incref(uav); - state->unordered_access_view[pipeline][idx] = uav; - wined3d_device_context_emit_set_unordered_access_view(context, pipeline, idx, uav, initial_count); - if (prev) - wined3d_unordered_access_view_decref(prev); + wined3d_device_context_emit_set_unordered_access_views(context, pipeline, start_idx, count, uavs, initial_counts); + for (i = 0; i < count; ++i) + { + struct wined3d_unordered_access_view *prev = state->unordered_access_view[pipeline][start_idx + i]; + struct wined3d_unordered_access_view *uav = uavs[i]; + + if (uav) + wined3d_unordered_access_view_incref(uav); + state->unordered_access_view[pipeline][start_idx + i] = uav; + if (prev) + wined3d_unordered_access_view_decref(prev); + } }
static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_context *context, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index c93be0a1007..4daf63f98cb 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -137,7 +137,7 @@ @ cdecl wined3d_device_context_set_state(ptr ptr) @ cdecl wined3d_device_context_set_stream_output(ptr long ptr long) @ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) -@ cdecl wined3d_device_context_set_unordered_access_view(ptr long long ptr long) +@ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_context_set_viewports(ptr long ptr) @ cdecl wined3d_device_context_unmap(ptr ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 75583c32f1c..ee43a22f977 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4834,9 +4834,9 @@ void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context enum wined3d_texture_stage_state state, unsigned int value) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_transform(struct wined3d_device_context *context, enum wined3d_transform_state state, const struct wined3d_matrix *matrix) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_unordered_access_view(struct wined3d_device_context *context, - enum wined3d_pipeline pipeline, unsigned int view_idx, struct wined3d_unordered_access_view *view, - unsigned int initial_count) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_unordered_access_views(struct wined3d_device_context *context, + enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, + struct wined3d_unordered_access_view *const *views, const unsigned int *initial_count) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_vertex_declaration(struct wined3d_device_context *context, struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_viewports(struct wined3d_device_context *context, unsigned int viewport_count, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 5de5026107f..d67a818b55c 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2525,9 +2525,9 @@ void __cdecl wined3d_device_context_set_stream_output(struct wined3d_device_cont struct wined3d_buffer *buffer, unsigned int offset); HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride); -void __cdecl wined3d_device_context_set_unordered_access_view(struct wined3d_device_context *context, - enum wined3d_pipeline pipeline, unsigned int idx, struct wined3d_unordered_access_view *uav, - unsigned int initial_count); +void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, + enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, + struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts); void __cdecl wined3d_device_context_set_vertex_declaration(struct wined3d_device_context *context, struct wined3d_vertex_declaration *declaration); void __cdecl wined3d_device_context_set_viewports(struct wined3d_device_context *context, unsigned int viewport_count,
Specifically, tweak and make use of the already existing WINED3D_CS_OP_RESET_STATE.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 40 +--------------------------------- dlls/wined3d/cs.c | 16 +++++++++++--- dlls/wined3d/device.c | 13 +++++++++-- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 2 +- include/wine/wined3d.h | 1 + 6 files changed, 28 insertions(+), 45 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 39144df3dc4..6f07bc92cdf 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -2591,49 +2591,11 @@ static void STDMETHODCALLTYPE d3d11_device_context_CSGetConstantBuffers(ID3D11De static void STDMETHODCALLTYPE d3d11_device_context_ClearState(ID3D11DeviceContext1 *iface) { struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - static const float blend_factor[] = {1.0f, 1.0f, 1.0f, 1.0f}; - unsigned int i, j;
TRACE("iface %p.\n", iface);
wined3d_mutex_lock(); - for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) - { - wined3d_device_context_set_shader(context->wined3d_context, i, NULL); - for (j = 0; j < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++j) - wined3d_device_context_set_constant_buffer(context->wined3d_context, i, j, NULL); - for (j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++j) - wined3d_device_context_set_shader_resource_view(context->wined3d_context, i, j, NULL); - for (j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++j) - wined3d_device_context_set_sampler(context->wined3d_context, i, j, NULL); - } - for (i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_source(context->wined3d_context, i, NULL, 0, 0); - } - wined3d_device_context_set_index_buffer(context->wined3d_context, NULL, WINED3DFMT_UNKNOWN, 0); - wined3d_device_context_set_vertex_declaration(context->wined3d_context, NULL); - wined3d_device_context_set_primitive_type(context->wined3d_context, WINED3D_PT_UNDEFINED, 0); - for (i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) - { - wined3d_device_context_set_rendertarget_view(context->wined3d_context, i, NULL, FALSE); - } - wined3d_device_context_set_depth_stencil_view(context->wined3d_context, NULL); - for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i) - { - for (j = 0; j < D3D11_PS_CS_UAV_REGISTER_COUNT; ++j) - wined3d_device_context_set_unordered_access_view(context->wined3d_context, i, j, NULL, ~0u); - } - ID3D11DeviceContext1_OMSetDepthStencilState(iface, NULL, 0); - ID3D11DeviceContext1_OMSetBlendState(iface, NULL, blend_factor, D3D11_DEFAULT_SAMPLE_MASK); - ID3D11DeviceContext1_RSSetViewports(iface, 0, NULL); - ID3D11DeviceContext1_RSSetScissorRects(iface, 0, NULL); - ID3D11DeviceContext1_RSSetState(iface, NULL); - for (i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_output(context->wined3d_context, i, NULL, 0); - } - wined3d_device_context_set_predication(context->wined3d_context, NULL, FALSE); + wined3d_device_context_reset_state(context->wined3d_context); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 77d40801414..b55bfdab866 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -359,6 +359,7 @@ struct wined3d_cs_push_constants struct wined3d_cs_reset_state { enum wined3d_cs_op opcode; + bool invalidate; };
struct wined3d_cs_callback @@ -2143,18 +2144,27 @@ static void wined3d_cs_mt_push_constants(struct wined3d_device_context *context,
static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) { + const struct wined3d_cs_reset_state *op = data; + unsigned int state; + state_cleanup(&cs->state); wined3d_state_reset(&cs->state, &cs->c.device->adapter->d3d_info); + if (op->invalidate) + { + for (state = 0; state <= STATE_HIGHEST; ++state) + device_invalidate_state(cs->c.device, state); + } }
-void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) +void wined3d_device_context_emit_reset_state(struct wined3d_device_context *context, bool invalidate) { struct wined3d_cs_reset_state *op;
- op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_RESET_STATE; + op->invalidate = invalidate;
- wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
static void wined3d_cs_exec_callback(struct wined3d_cs *cs, const void *data) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2c8ebba8844..08f986dd5e2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1169,7 +1169,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device) wined3d_texture_decref(texture); }
- wined3d_cs_emit_reset_state(device->cs); + wined3d_device_context_emit_reset_state(&device->cs->c, false); state_cleanup(state);
wine_rb_clear(&device->samplers, device_free_sampler, NULL); @@ -1649,6 +1649,15 @@ void CDECL wined3d_device_context_get_scissor_rects(const struct wined3d_device_ *rect_count = state->scissor_rect_count; }
+void CDECL wined3d_device_context_reset_state(struct wined3d_device_context *context) +{ + TRACE("context %p.\n", context); + + state_cleanup(context->state); + wined3d_state_reset(context->state, &context->device->adapter->d3d_info); + wined3d_device_context_emit_reset_state(context, true); +} + void CDECL wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state) { const struct wined3d_light_info *light; @@ -5417,7 +5426,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (reset_state) { TRACE("Resetting state.\n"); - wined3d_cs_emit_reset_state(device->cs); + wined3d_device_context_emit_reset_state(&device->cs->c, false); state_cleanup(state);
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry) diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 901e9bee621..84412515c39 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -114,6 +114,7 @@ @ cdecl wined3d_device_context_get_viewports(ptr ptr ptr) @ cdecl wined3d_device_context_issue_query(ptr ptr long) @ cdecl wined3d_device_context_map(ptr ptr long ptr ptr long) +@ cdecl wined3d_device_context_reset_state(ptr) @ cdecl wined3d_device_context_resolve_sub_resource(ptr ptr long ptr long long) @ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long) @ cdecl wined3d_device_context_set_constant_buffer(ptr long long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fadad706af4..af9beffc142 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4737,7 +4737,6 @@ void wined3d_device_context_emit_clear_uav_uint(struct wined3d_device_context *c void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, unsigned int swap_interval, DWORD flags) DECLSPEC_HIDDEN; -void wined3d_cs_emit_reset_state(struct wined3d_cs *cs) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, @@ -4775,6 +4774,7 @@ void wined3d_device_context_emit_draw(struct wined3d_device_context *context, bool indexed) DECLSPEC_HIDDEN; void wined3d_device_context_emit_generate_mipmaps(struct wined3d_device_context *context, struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_reset_state(struct wined3d_device_context *context, bool invalidate) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_blend_state(struct wined3d_device_context *context, struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 0be192b0f01..812c042cdd7 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2480,6 +2480,7 @@ void __cdecl wined3d_device_context_issue_query(struct wined3d_device_context *c HRESULT __cdecl wined3d_device_context_map(struct wined3d_device_context *context, struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, unsigned int flags); +void __cdecl wined3d_device_context_reset_state(struct wined3d_device_context *context); void __cdecl wined3d_device_context_resolve_sub_resource(struct wined3d_device_context *context, struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, enum wined3d_format_id format_id);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 35 +++++++++++------------- dlls/wined3d/cs.c | 49 ++++++++++++++++------------------ dlls/wined3d/device.c | 40 +++++++++++---------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 10 ++----- include/wine/wined3d.h | 10 +++++-- 6 files changed, 65 insertions(+), 81 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 578e572797a..79cc7e8c8da 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1172,24 +1172,22 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetDepthStencilState(ID3D11 static void STDMETHODCALLTYPE d3d11_device_context_SOSetTargets(ID3D11DeviceContext1 *iface, UINT buffer_count, ID3D11Buffer *const *buffers, const UINT *offsets) { + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0}; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); - unsigned int count, i; + unsigned int i;
TRACE("iface %p, buffer_count %u, buffers %p, offsets %p.\n", iface, buffer_count, buffers, offsets);
- count = min(buffer_count, D3D11_SO_BUFFER_SLOT_COUNT); - wined3d_mutex_lock(); - for (i = 0; i < count; ++i) + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]);
- wined3d_device_context_set_stream_output(context->wined3d_context, i, - buffer ? buffer->wined3d_buffer : NULL, offsets ? offsets[i] : 0); - } - for (; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_output(context->wined3d_context, i, NULL, 0); + outputs[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + outputs[i].offset = offsets ? offsets[i] : 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_outputs(context->wined3d_context, outputs); wined3d_mutex_unlock(); }
@@ -4895,25 +4893,22 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetDepthStencilState(ID3D10Device1 static void STDMETHODCALLTYPE d3d10_device_SOSetTargets(ID3D10Device1 *iface, UINT target_count, ID3D10Buffer *const *targets, const UINT *offsets) { + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0}; struct d3d_device *device = impl_from_ID3D10Device(iface); - unsigned int count, i; + unsigned int i;
TRACE("iface %p, target_count %u, targets %p, offsets %p.\n", iface, target_count, targets, offsets);
- count = min(target_count, D3D10_SO_BUFFER_SLOT_COUNT); - wined3d_mutex_lock(); - for (i = 0; i < count; ++i) + for (i = 0; i < target_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(targets[i]);
- wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i]); + outputs[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + outputs[i].offset = offsets ? offsets[i] : 0; }
- for (i = count; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, NULL, 0); - } + wined3d_mutex_lock(); + wined3d_device_context_set_stream_outputs(device->immediate_context.wined3d_context, outputs); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index c3702ab1527..0f950f23f0f 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -114,7 +114,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCE, WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, - WINED3D_CS_OP_SET_STREAM_OUTPUT, + WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_TEXTURE, @@ -266,12 +266,10 @@ struct wined3d_cs_set_stream_source_freq UINT flags; };
-struct wined3d_cs_set_stream_output +struct wined3d_cs_set_stream_outputs { enum wined3d_cs_op opcode; - UINT stream_idx; - struct wined3d_buffer *buffer; - UINT offset; + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; };
struct wined3d_cs_set_index_buffer @@ -608,7 +606,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); - WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUT); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); @@ -1477,35 +1475,34 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_stream_outputs(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_stream_output *op = data; - struct wined3d_stream_output *stream; - struct wined3d_buffer *prev; + const struct wined3d_cs_set_stream_outputs *op = data; + unsigned int i;
- stream = &cs->state.stream_output[op->stream_idx]; - prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; + for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) + { + struct wined3d_buffer *prev = cs->state.stream_output[i].buffer; + struct wined3d_buffer *buffer = op->outputs[i].buffer;
- if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); + if (buffer) + InterlockedIncrement(&buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + }
+ memcpy(cs->state.stream_output, op->outputs, sizeof(op->outputs)); device_invalidate_state(cs->c.device, STATE_STREAM_OUTPUT); }
-void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset) +void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) { - struct wined3d_cs_set_stream_output *op; + struct wined3d_cs_set_stream_outputs *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; - op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; + op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUTS; + memcpy(op->outputs, outputs, sizeof(op->outputs));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2949,7 +2946,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, - /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, + /* WINED3D_CS_OP_SET_STREAM_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index faf11d25dcb..b846875d865 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1676,11 +1676,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte wined3d_device_context_emit_set_depth_stencil_view(context, state->fb.depth_stencil); wined3d_device_context_emit_set_vertex_declaration(context, state->vertex_declaration);
- for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) - { - wined3d_device_context_emit_set_stream_output(context, i, - state->stream_output[i].buffer, state->stream_output[i].offset); - } + wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
for (i = 0; i < WINED3D_MAX_STREAMS; ++i) { @@ -2332,30 +2328,26 @@ void CDECL wined3d_device_context_set_vertex_declaration(struct wined3d_device_c wined3d_vertex_declaration_decref(prev); }
-void CDECL wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx, - struct wined3d_buffer *buffer, unsigned int offset) +void CDECL wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) { - struct wined3d_stream_output *stream; - struct wined3d_buffer *prev_buffer; + struct wined3d_state *state = context->state; + unsigned int i;
- TRACE("context %p, idx %u, buffer %p, offset %u.\n", context, idx, buffer, offset); + TRACE("context %p, outputs %p.\n", context, outputs);
- if (idx >= WINED3D_MAX_STREAM_OUTPUT_BUFFERS) + wined3d_device_context_emit_set_stream_outputs(context, outputs); + for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) { - WARN("Invalid stream output %u.\n", idx); - return; + struct wined3d_buffer *prev_buffer = state->stream_output[i].buffer; + struct wined3d_buffer *buffer = outputs[i].buffer; + + if (buffer) + wined3d_buffer_incref(buffer); + state->stream_output[i] = outputs[i]; + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } - - stream = &context->state->stream_output[idx]; - prev_buffer = stream->buffer; - - if (buffer) - wined3d_buffer_incref(buffer); - stream->buffer = buffer; - stream->offset = offset; - wined3d_device_context_emit_set_stream_output(context, idx, buffer, offset); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); }
void CDECL wined3d_device_context_draw(struct wined3d_device_context *context, unsigned int start_vertex, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 4daf63f98cb..37c600cfc55 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -135,7 +135,7 @@ @ cdecl wined3d_device_context_set_shader(ptr long ptr) @ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr) @ cdecl wined3d_device_context_set_state(ptr ptr) -@ cdecl wined3d_device_context_set_stream_output(ptr long ptr long) +@ cdecl wined3d_device_context_set_stream_outputs(ptr ptr) @ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ee43a22f977..270952c936e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3649,12 +3649,6 @@ struct wined3d_rasterizer_state struct wine_rb_entry entry; };
-struct wined3d_stream_output -{ - struct wined3d_buffer *buffer; - UINT offset; -}; - #define LIGHTMAP_SIZE 43 #define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
@@ -4824,8 +4818,8 @@ void wined3d_device_context_emit_set_shader(struct wined3d_device_context *conte void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_shader_resource_view *const *views) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d67a818b55c..028bbee8f41 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2212,6 +2212,12 @@ struct wined3d_stateblock_state struct wined3d_light_state *light_state; };
+struct wined3d_stream_output +{ + struct wined3d_buffer *buffer; + unsigned int offset; +}; + struct wined3d_parent_ops { void (__stdcall *wined3d_object_destroyed)(void *parent); @@ -2521,8 +2527,8 @@ void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_dev enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_shader_resource_view *const *views); void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state); -void __cdecl wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx, - struct wined3d_buffer *buffer, unsigned int offset); +void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/d3d11_private.h | 10 +++ dlls/d3d11/device.c | 154 ++++++++++++++++++++++++++++++++++++- dlls/wined3d/cs.c | 103 +++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 4 + include/wine/wined3d.h | 6 ++ 5 files changed, 276 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 2b5a51afbd1..afbde9a4bfb 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -583,6 +583,16 @@ struct d3d_device SIZE_T context_state_count; };
+struct d3d11_command_list +{ + ID3D11CommandList ID3D11CommandList_iface; + LONG refcount; + + ID3D11Device2 *device; + struct wined3d_command_list *wined3d_list; + struct wined3d_private_store private_store; +}; + static inline struct d3d_device *impl_from_ID3D11Device(ID3D11Device *iface) { return CONTAINING_RECORD((ID3D11Device2 *)iface, struct d3d_device, ID3D11Device2_iface); diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 6f07bc92cdf..e832d8e68d3 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -330,6 +330,123 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state d3d_device_context_state_AddRef(&state->ID3DDeviceContextState_iface); }
+/* ID3D11CommandList methods */ + +static inline struct d3d11_command_list *impl_from_ID3D11CommandList(ID3D11CommandList *iface) +{ + return CONTAINING_RECORD(iface, struct d3d11_command_list, ID3D11CommandList_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_command_list_QueryInterface(ID3D11CommandList *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3D11CommandList) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + ID3D11CommandList_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_command_list_AddRef(ID3D11CommandList *iface) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + ULONG refcount = InterlockedIncrement(&list->refcount); + + TRACE("%p increasing refcount to %u.\n", list, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_command_list_Release(ID3D11CommandList *iface) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + ULONG refcount = InterlockedDecrement(&list->refcount); + + TRACE("%p decreasing refcount to %u.\n", list, refcount); + + if (!refcount) + { + wined3d_mutex_lock(); + wined3d_command_list_decref(list->wined3d_list); + wined3d_mutex_unlock(); + ID3D11Device2_Release(list->device); + heap_free(list); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_command_list_GetDevice(ID3D11CommandList *iface, ID3D11Device **device) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)list->device; + ID3D11Device2_AddRef(list->device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_command_list_GetPrivateData(ID3D11CommandList *iface, REFGUID guid, + UINT *data_size, void *data) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&list->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_command_list_SetPrivateData(ID3D11CommandList *iface, REFGUID guid, + UINT data_size, const void *data) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&list->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_command_list_SetPrivateDataInterface(ID3D11CommandList *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&list->private_store, guid, data); +} + +static UINT STDMETHODCALLTYPE d3d11_command_list_GetContextFlags(ID3D11CommandList *iface) +{ + TRACE("iface %p.\n", iface); + + return 0; +} + +static const struct ID3D11CommandListVtbl d3d11_command_list_vtbl = +{ + /* IUnknown methods */ + d3d11_command_list_QueryInterface, + d3d11_command_list_AddRef, + d3d11_command_list_Release, + /* ID3D11DeviceChild methods */ + d3d11_command_list_GetDevice, + d3d11_command_list_GetPrivateData, + d3d11_command_list_SetPrivateData, + d3d11_command_list_SetPrivateDataInterface, + /* ID3D11CommandList methods */ + d3d11_command_list_GetContextFlags, +}; + /* ID3D11DeviceContext - immediate context methods */
static inline struct d3d11_device_context *impl_from_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) @@ -2629,9 +2746,44 @@ static UINT STDMETHODCALLTYPE d3d11_device_context_GetContextFlags(ID3D11DeviceC static HRESULT STDMETHODCALLTYPE d3d11_device_context_FinishCommandList(ID3D11DeviceContext1 *iface, BOOL restore, ID3D11CommandList **command_list) { + struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + struct d3d11_command_list *object; + HRESULT hr; + TRACE("iface %p, restore %#x, command_list %p.\n", iface, restore, command_list);
- return DXGI_ERROR_INVALID_CALL; + if (context->type == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + WARN("Attempt to record command list on an immediate context; returning DXGI_ERROR_INVALID_CALL.\n"); + return DXGI_ERROR_INVALID_CALL; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_mutex_lock(); + + if (FAILED(hr = wined3d_deferred_context_record_command_list(context->wined3d_context, + !!restore, &object->wined3d_list))) + { + WARN("Failed to record wined3d command list, hr %#x.\n", hr); + heap_free(object); + return hr; + } + + wined3d_mutex_unlock(); + + object->ID3D11CommandList_iface.lpVtbl = &d3d11_command_list_vtbl; + object->refcount = 1; + object->device = &context->device->ID3D11Device2_iface; + wined3d_private_store_init(&object->private_store); + + ID3D11Device2_AddRef(object->device); + + TRACE("Created command list %p.\n", object); + *command_list = &object->ID3D11CommandList_iface; + + return S_OK; }
static void STDMETHODCALLTYPE d3d11_device_context_CopySubresourceRegion1(ID3D11DeviceContext1 *iface, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index b55bfdab866..db1c811a1f1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -26,6 +26,59 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
#define WINED3D_INITIAL_CS_SIZE 4096
+struct wined3d_command_list +{ + LONG refcount; + + struct wined3d_device *device; + + SIZE_T data_size; + void *data; + + SIZE_T resource_count; + struct wined3d_resource **resources; +}; + +static void wined3d_command_list_destroy_object(void *object) +{ + struct wined3d_command_list *list = object; + + TRACE("list %p.\n", list); + + heap_free(list->resources); + heap_free(list->data); + heap_free(list); +} + +ULONG CDECL wined3d_command_list_incref(struct wined3d_command_list *list) +{ + ULONG refcount = InterlockedIncrement(&list->refcount); + + TRACE("%p increasing refcount to %u.\n", list, refcount); + + return refcount; +} + +ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list) +{ + ULONG refcount = InterlockedDecrement(&list->refcount); + struct wined3d_device *device = list->device; + + TRACE("%p decreasing refcount to %u.\n", list, refcount); + + if (!refcount) + { + SIZE_T i; + + for (i = 0; i < list->resource_count; ++i) + wined3d_resource_decref(list->resources[i]); + + wined3d_cs_destroy_object(device->cs, wined3d_command_list_destroy_object, list); + } + + return refcount; +} + enum wined3d_cs_op { WINED3D_CS_OP_NOP, @@ -3333,3 +3386,53 @@ void CDECL wined3d_deferred_context_destroy(struct wined3d_device_context *conte heap_free(deferred->data); heap_free(deferred); } + +HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device_context *context, + bool restore, struct wined3d_command_list **list) +{ + struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + struct wined3d_command_list *object; + + TRACE("context %p, list %p.\n", context, list); + + if (restore) + { + FIXME("Restoring context state is not implemented.\n"); + return E_NOTIMPL; + } + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->refcount = 1; + object->device = deferred->c.device; + + if (!(object->data = heap_alloc(deferred->data_size))) + { + heap_free(object); + return E_OUTOFMEMORY; + } + object->data_size = deferred->data_size; + memcpy(object->data, deferred->data, deferred->data_size); + + if (!(object->resources = heap_alloc(deferred->resource_count * sizeof(*object->resources)))) + { + heap_free(object->data); + heap_free(object); + return E_OUTOFMEMORY; + } + object->resource_count = deferred->resource_count; + memcpy(object->resources, deferred->resources, deferred->resource_count * sizeof(*object->resources)); + /* Transfer our references to the resources to the command list. */ + + deferred->data_size = 0; + deferred->resource_count = 0; + + /* This is in fact recorded into a subsequent command list. */ + wined3d_device_context_reset_state(&deferred->c); + + TRACE("Created command list %p.\n", object); + *list = object; + + return S_OK; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 84412515c39..6683b3bc30f 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -33,8 +33,12 @@ @ cdecl wined3d_buffer_get_resource(ptr) @ cdecl wined3d_buffer_incref(ptr)
+@ cdecl wined3d_command_list_decref(ptr) +@ cdecl wined3d_command_list_incref(ptr) + @ cdecl wined3d_deferred_context_create(ptr ptr) @ cdecl wined3d_deferred_context_destroy(ptr) +@ cdecl wined3d_deferred_context_record_command_list(ptr long ptr)
@ cdecl wined3d_depth_stencil_state_create(ptr ptr ptr ptr ptr) @ cdecl wined3d_depth_stencil_state_decref(ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 812c042cdd7..bb6bf58a822 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2221,6 +2221,7 @@ struct wined3d; struct wined3d_adapter; struct wined3d_blend_state; struct wined3d_buffer; +struct wined3d_command_list; struct wined3d_depth_stencil_state; struct wined3d_device; struct wined3d_device_context; @@ -2340,8 +2341,13 @@ void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer); struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer); ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
+ULONG __cdecl wined3d_command_list_decref(struct wined3d_command_list *list); +ULONG __cdecl wined3d_command_list_incref(struct wined3d_command_list *list); + HRESULT __cdecl wined3d_deferred_context_create(struct wined3d_device *device, struct wined3d_device_context **context); void __cdecl wined3d_deferred_context_destroy(struct wined3d_device_context *context); +HRESULT __cdecl wined3d_deferred_context_record_command_list(struct wined3d_device_context *context, + bool restore, struct wined3d_command_list **list);
HRESULT __cdecl wined3d_depth_stencil_state_create(struct wined3d_device *device, const struct wined3d_depth_stencil_state_desc *desc, void *parent,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 20 ++++++++--- dlls/wined3d/cs.c | 54 ++++------------------------ dlls/wined3d/device.c | 64 +++++++++------------------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +-- include/wine/wined3d.h | 2 +- 6 files changed, 41 insertions(+), 105 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 79cc7e8c8da..77b2f281aef 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -839,9 +839,15 @@ static void STDMETHODCALLTYPE d3d11_device_context_IASetVertexBuffers(ID3D11Devi for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); + struct wined3d_stream_state stream;
- wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + stream.buffer = buffer ? buffer->wined3d_buffer : NULL; + stream.offset = offsets[i]; + stream.stride = strides[i]; + stream.frequency = 1; + stream.flags = 0; + + wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, &stream); } wined3d_mutex_unlock(); } @@ -4690,9 +4696,15 @@ static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *ifa for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); + struct wined3d_stream_state stream;
- wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + stream.buffer = buffer ? buffer->wined3d_buffer : NULL; + stream.offset = offsets[i]; + stream.stride = strides[i]; + stream.frequency = 1; + stream.flags = 0; + + wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, &stream); } wined3d_mutex_unlock(); } diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 0f950f23f0f..83b9e906fb1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -113,7 +113,6 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCE, - WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, @@ -253,17 +252,7 @@ struct wined3d_cs_set_stream_source { enum wined3d_cs_op opcode; UINT stream_idx; - struct wined3d_buffer *buffer; - UINT offset; - UINT stride; -}; - -struct wined3d_cs_set_stream_source_freq -{ - enum wined3d_cs_op opcode; - UINT stream_idx; - UINT frequency; - UINT flags; + struct wined3d_stream_state state; };
struct wined3d_cs_set_stream_outputs @@ -605,7 +594,6 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); - WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); @@ -1423,12 +1411,10 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void
stream = &cs->state.streams[op->stream_idx]; prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; - stream->stride = op->stride; + *stream = op->state;
- if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); + if (op->state.buffer) + InterlockedIncrement(&op->state.buffer->resource.bind_count); if (prev) InterlockedDecrement(&prev->resource.bind_count);
@@ -1436,45 +1422,18 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void }
void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) + const struct wined3d_stream_state *state) { struct wined3d_cs_set_stream_source *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; - op->stride = stride; + op->state = *state;
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_stream_source_freq *op = data; - struct wined3d_stream_state *stream; - - stream = &cs->state.streams[op->stream_idx]; - stream->frequency = op->frequency; - stream->flags = op->flags; - - device_invalidate_state(cs->c.device, STATE_STREAMSRC); -} - -void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) -{ - struct wined3d_cs_set_stream_source_freq *op; - - op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; - op->stream_idx = stream_idx; - op->frequency = frequency; - op->flags = flags; - - wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); -} - static void wined3d_cs_exec_set_stream_outputs(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_stream_outputs *op = data; @@ -2945,7 +2904,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, - /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, /* WINED3D_CS_OP_SET_STREAM_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b846875d865..e045c8ad3a4 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1274,23 +1274,6 @@ HRESULT CDECL wined3d_device_context_get_stream_source(const struct wined3d_devi return WINED3D_OK; }
-static void wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider) -{ - struct wined3d_stream_state *stream; - UINT old_flags, old_freq; - - TRACE("device %p, stream_idx %u, divider %#x.\n", device, stream_idx, divider); - - stream = &device->cs->c.state->streams[stream_idx]; - old_flags = stream->flags; - old_freq = stream->frequency; - - stream->flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA); - stream->frequency = divider & 0x7fffff; - if (stream->frequency != old_freq || stream->flags != old_flags) - wined3d_cs_emit_set_stream_source_freq(device->cs, stream_idx, stream->frequency, stream->flags); -} - static void wined3d_device_set_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix) { @@ -1679,10 +1662,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
for (i = 0; i < WINED3D_MAX_STREAMS; ++i) - { - wined3d_device_context_emit_set_stream_source(context, i, state->streams[i].buffer, - state->streams[i].offset, state->streams[i].stride); - } + wined3d_device_context_emit_set_stream_source(context, i, &state->streams[i]);
wined3d_device_context_emit_set_index_buffer(context, state->index_buffer, state->index_format, state->index_offset); @@ -2238,42 +2218,38 @@ void CDECL wined3d_device_context_set_predication(struct wined3d_device_context }
HRESULT CDECL wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) + unsigned int stream_idx, const struct wined3d_stream_state *src_stream) { - struct wined3d_stream_state *stream; + struct wined3d_buffer *buffer = src_stream->buffer; + struct wined3d_stream_state *dst_stream; struct wined3d_buffer *prev_buffer;
- TRACE("context %p, stream_idx %u, buffer %p, offset %u, stride %u.\n", - context, stream_idx, buffer, offset, stride); + TRACE("context %p, stream_idx %u, src_stream %p.\n", context, stream_idx, src_stream);
if (stream_idx >= WINED3D_MAX_STREAMS) { WARN("Stream index %u out of range.\n", stream_idx); return WINED3DERR_INVALIDCALL; } - else if (offset & 0x3) + else if (src_stream->offset & 0x3) { - WARN("Offset %u is not 4 byte aligned.\n", offset); + WARN("Offset %u is not 4 byte aligned.\n", src_stream->offset); return WINED3DERR_INVALIDCALL; }
- stream = &context->state->streams[stream_idx]; - prev_buffer = stream->buffer; + dst_stream = &context->state->streams[stream_idx]; + prev_buffer = dst_stream->buffer;
- if (prev_buffer == buffer - && stream->stride == stride - && stream->offset == offset) + if (!memcmp(src_stream, dst_stream, sizeof(*src_stream))) { - TRACE("Application is setting the old values over, nothing to do.\n"); - return WINED3D_OK; + TRACE("Application is setting the old values over, nothing to do.\n"); + return WINED3D_OK; }
- stream->buffer = buffer; - stream->stride = stride; - stream->offset = offset; + *dst_stream = *src_stream; if (buffer) wined3d_buffer_incref(buffer); - wined3d_device_context_emit_set_stream_source(context, stream_idx, buffer, offset, stride); + wined3d_device_context_emit_set_stream_source(context, stream_idx, src_stream); if (prev_buffer) wined3d_buffer_decref(prev_buffer);
@@ -3930,19 +3906,11 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, if (changed->scissorRect) wined3d_device_context_set_scissor_rects(context, 1, &state->scissor_rect);
- map = changed->streamSource; + map = changed->streamSource | changed->streamFreq; while (map) { i = wined3d_bit_scan(&map); - wined3d_device_context_set_stream_source(context, i, state->streams[i].buffer, - state->streams[i].offset, state->streams[i].stride); - } - map = changed->streamFreq; - while (map) - { - i = wined3d_bit_scan(&map); - wined3d_device_set_stream_source_freq(device, i, - state->streams[i].frequency | state->streams[i].flags); + wined3d_device_context_set_stream_source(context, i, &state->streams[i]); }
map = changed->textures; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 37c600cfc55..7a5659dbf41 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -136,7 +136,7 @@ @ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr) @ cdecl wined3d_device_context_set_state(ptr ptr) @ cdecl wined3d_device_context_set_stream_outputs(ptr ptr) -@ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) +@ cdecl wined3d_device_context_set_stream_source(ptr long ptr) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_context_set_viewports(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 270952c936e..7ca6a8d7e2e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4743,8 +4743,6 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, - UINT frequency, UINT flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_init_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; @@ -4821,7 +4819,7 @@ void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) DECLSPEC_HIDDEN; + const struct wined3d_stream_state *state) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 028bbee8f41..000423139d0 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2530,7 +2530,7 @@ void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *con void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride); + unsigned int stream_idx, const struct wined3d_stream_state *stream); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/tests/d3d11.c | 39 +++++++++++++-------------------------- dlls/wined3d/cs.c | 11 ++++------- 2 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index d799bed25f4..8da0cfaa8bf 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -32281,15 +32281,7 @@ static void test_deferred_context_state(void) ID3D11Buffer_Release(ret_buffer);
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list1); - todo_wine ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); - if (hr != S_OK) - { - ID3D11DeviceContext_Release(deferred); - ID3D11Buffer_Release(blue_buffer); - ID3D11Buffer_Release(green_buffer); - release_test_context(&test_context); - return; - } + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
ID3D11DeviceContext_PSGetConstantBuffers(deferred, 0, 1, &ret_buffer); ok(ret_buffer == blue_buffer, "Got unexpected buffer %p.\n", ret_buffer); @@ -32310,7 +32302,9 @@ static void test_deferred_context_state(void) ID3D11DeviceContext_PSSetConstantBuffers(immediate, 0, 1, &green_buffer); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, FALSE); ID3D11DeviceContext_PSGetConstantBuffers(immediate, 0, 1, &ret_buffer); - ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer); + todo_wine ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer); + if (ret_buffer) + ID3D11Buffer_Release(ret_buffer);
ID3D11CommandList_Release(list2); ID3D11CommandList_Release(list1); @@ -32484,16 +32478,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(deferred, test_context.backbuffer_rtv, green);
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list1); - todo_wine ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); - if (hr != S_OK) - { - ID3D11BlendState_Release(red_blend); - ID3D11BlendState_Release(green_blend); - ID3D11BlendState_Release(blue_blend); - ID3D11DeviceContext_Release(deferred); - release_test_context(&test_context); - return; - } + ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
hr = ID3D11DeviceContext_FinishCommandList(deferred, TRUE, &list2); ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr); @@ -32503,12 +32488,12 @@ static void test_deferred_context_rendering(void)
ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, TRUE); @@ -32524,7 +32509,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list2); ID3D11CommandList_Release(list1); @@ -32550,7 +32535,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(immediate, rtv, blue); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - ok(color == 0xffff0000, "Got unexpected color %#08x.\n", color); + todo_wine ok(color == 0xffff0000, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list1); ID3D11DeviceContext_Release(deferred); @@ -32584,10 +32569,12 @@ static void test_deferred_context_rendering(void) set_viewport(immediate, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f); draw_color_quad(&test_context, &white); color = get_texture_color(test_context.backbuffer, 320, 240); - ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color); + todo_wine ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_OMGetBlendState(immediate, &ret_blend, blend_factor, &sample_mask); - ok(!ret_blend, "Got unexpected blend state %p.\n", ret_blend); + todo_wine ok(!ret_blend, "Got unexpected blend state %p.\n", ret_blend); + if (ret_blend) + ID3D11BlendState_Release(ret_blend);
ID3D11CommandList_Release(list1); ID3D11DeviceContext_Release(deferred); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index db1c811a1f1..1e082ce724d 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3395,12 +3395,6 @@ HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device
TRACE("context %p, list %p.\n", context, list);
- if (restore) - { - FIXME("Restoring context state is not implemented.\n"); - return E_NOTIMPL; - } - if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
@@ -3429,7 +3423,10 @@ HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device deferred->resource_count = 0;
/* This is in fact recorded into a subsequent command list. */ - wined3d_device_context_reset_state(&deferred->c); + if (restore) + wined3d_device_context_set_state(&deferred->c, deferred->c.state); + else + wined3d_device_context_reset_state(&deferred->c);
TRACE("Created command list %p.\n", object); *list = object;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 37 ++++++++++----------- dlls/wined3d/cs.c | 53 ++++++++++++++++-------------- dlls/wined3d/device.c | 59 ++++++++++++++++++---------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +-- include/wine/wined3d.h | 4 +-- 6 files changed, 85 insertions(+), 74 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 77b2f281aef..33aa098152d 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -829,26 +829,26 @@ static void STDMETHODCALLTYPE d3d11_device_context_IASetInputLayout(ID3D11Device static void STDMETHODCALLTYPE d3d11_device_context_IASetVertexBuffers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers, const UINT *strides, const UINT *offsets) { + struct wined3d_stream_state streams[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int i;
TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p.\n", iface, start_slot, buffer_count, buffers, strides, offsets);
- wined3d_mutex_lock(); for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); - struct wined3d_stream_state stream;
- stream.buffer = buffer ? buffer->wined3d_buffer : NULL; - stream.offset = offsets[i]; - stream.stride = strides[i]; - stream.frequency = 1; - stream.flags = 0; - - wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, &stream); + streams[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + streams[i].offset = offsets[i]; + streams[i].stride = strides[i]; + streams[i].frequency = 1; + streams[i].flags = 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_sources(context->wined3d_context, start_slot, buffer_count, streams); wined3d_mutex_unlock(); }
@@ -4686,26 +4686,27 @@ static void STDMETHODCALLTYPE d3d10_device_IASetInputLayout(ID3D10Device1 *iface static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *iface, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers, const UINT *strides, const UINT *offsets) { + struct wined3d_stream_state streams[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; struct d3d_device *device = impl_from_ID3D10Device(iface); unsigned int i;
TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p\n", iface, start_slot, buffer_count, buffers, strides, offsets);
- wined3d_mutex_lock(); for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); - struct wined3d_stream_state stream;
- stream.buffer = buffer ? buffer->wined3d_buffer : NULL; - stream.offset = offsets[i]; - stream.stride = strides[i]; - stream.frequency = 1; - stream.flags = 0; - - wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, &stream); + streams[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + streams[i].offset = offsets[i]; + streams[i].stride = strides[i]; + streams[i].frequency = 1; + streams[i].flags = 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_sources(device->immediate_context.wined3d_context, + start_slot, buffer_count, streams); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 83b9e906fb1..3ee6c255e67 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -112,7 +112,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_RENDERTARGET_VIEW, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, - WINED3D_CS_OP_SET_STREAM_SOURCE, + WINED3D_CS_OP_SET_STREAM_SOURCES, WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, @@ -248,11 +248,12 @@ struct wined3d_cs_set_vertex_declaration struct wined3d_vertex_declaration *declaration; };
-struct wined3d_cs_set_stream_source +struct wined3d_cs_set_stream_sources { enum wined3d_cs_op opcode; - UINT stream_idx; - struct wined3d_stream_state state; + unsigned int start_idx; + unsigned int count; + struct wined3d_stream_state streams[1]; };
struct wined3d_cs_set_stream_outputs @@ -593,7 +594,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); - WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCES); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); @@ -1403,33 +1404,37 @@ void wined3d_device_context_emit_set_vertex_declaration(struct wined3d_device_co wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_stream_sources(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_stream_source *op = data; - struct wined3d_stream_state *stream; - struct wined3d_buffer *prev; + const struct wined3d_cs_set_stream_sources *op = data; + unsigned int i;
- stream = &cs->state.streams[op->stream_idx]; - prev = stream->buffer; - *stream = op->state; + for (i = 0; i < op->count; ++i) + { + struct wined3d_buffer *prev = cs->state.streams[op->start_idx + i].buffer; + struct wined3d_buffer *buffer = op->streams[i].buffer;
- if (op->state.buffer) - InterlockedIncrement(&op->state.buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); + if (buffer) + InterlockedIncrement(&buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + }
+ memcpy(&cs->state.streams[op->start_idx], op->streams, op->count * sizeof(*op->streams)); device_invalidate_state(cs->c.device, STATE_STREAMSRC); }
-void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - const struct wined3d_stream_state *state) +void wined3d_device_context_emit_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) { - struct wined3d_cs_set_stream_source *op; + struct wined3d_cs_set_stream_sources *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; - op->stream_idx = stream_idx; - op->state = *state; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_stream_sources, streams[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCES; + op->start_idx = start_idx; + op->count = count; + memcpy(op->streams, streams, count * sizeof(*streams));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2903,7 +2908,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, - /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, + /* WINED3D_CS_OP_SET_STREAM_SOURCES */ wined3d_cs_exec_set_stream_sources, /* WINED3D_CS_OP_SET_STREAM_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e045c8ad3a4..8dcf5ffdfe6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1661,8 +1661,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte
wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
- for (i = 0; i < WINED3D_MAX_STREAMS; ++i) - wined3d_device_context_emit_set_stream_source(context, i, &state->streams[i]); + wined3d_device_context_emit_set_stream_sources(context, 0, WINED3D_MAX_STREAMS, state->streams);
wined3d_device_context_emit_set_index_buffer(context, state->index_buffer, state->index_format, state->index_offset); @@ -2217,41 +2216,47 @@ void CDECL wined3d_device_context_set_predication(struct wined3d_device_context wined3d_query_decref(prev); }
-HRESULT CDECL wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, const struct wined3d_stream_state *src_stream) +HRESULT CDECL wined3d_device_context_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) { - struct wined3d_buffer *buffer = src_stream->buffer; - struct wined3d_stream_state *dst_stream; - struct wined3d_buffer *prev_buffer; + struct wined3d_state *state = context->state; + unsigned int i;
- TRACE("context %p, stream_idx %u, src_stream %p.\n", context, stream_idx, src_stream); + TRACE("context %p, start_idx %u, count %u, streams %p.\n", context, start_idx, count, streams);
- if (stream_idx >= WINED3D_MAX_STREAMS) + if (start_idx >= WINED3D_MAX_STREAMS) { - WARN("Stream index %u out of range.\n", stream_idx); - return WINED3DERR_INVALIDCALL; - } - else if (src_stream->offset & 0x3) - { - WARN("Offset %u is not 4 byte aligned.\n", src_stream->offset); + WARN("Start index %u is out of range.\n", start_idx); return WINED3DERR_INVALIDCALL; }
- dst_stream = &context->state->streams[stream_idx]; - prev_buffer = dst_stream->buffer; + count = min(count, WINED3D_MAX_STREAMS - start_idx);
- if (!memcmp(src_stream, dst_stream, sizeof(*src_stream))) + for (i = 0; i < count; ++i) { - TRACE("Application is setting the old values over, nothing to do.\n"); + if (streams[i].offset & 0x3) + { + WARN("Offset %u is not 4 byte aligned.\n", streams[i].offset); + return WINED3DERR_INVALIDCALL; + } + } + + if (!memcmp(streams, &state->streams[start_idx], count * sizeof(*streams))) return WINED3D_OK; - }
- *dst_stream = *src_stream; - if (buffer) - wined3d_buffer_incref(buffer); - wined3d_device_context_emit_set_stream_source(context, stream_idx, src_stream); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); + wined3d_device_context_emit_set_stream_sources(context, start_idx, count, streams); + for (i = 0; i < count; ++i) + { + struct wined3d_buffer *prev = state->streams[start_idx + i].buffer; + struct wined3d_buffer *buffer = streams[i].buffer; + + state->streams[start_idx + i] = streams[i]; + + if (buffer) + wined3d_buffer_incref(buffer); + if (prev) + wined3d_buffer_decref(prev); + }
return WINED3D_OK; } @@ -3910,7 +3915,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, while (map) { i = wined3d_bit_scan(&map); - wined3d_device_context_set_stream_source(context, i, &state->streams[i]); + wined3d_device_context_set_stream_sources(context, i, 1, &state->streams[i]); }
map = changed->textures; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 7a5659dbf41..bcdeb38b96b 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -136,7 +136,7 @@ @ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr) @ cdecl wined3d_device_context_set_state(ptr ptr) @ cdecl wined3d_device_context_set_stream_outputs(ptr ptr) -@ cdecl wined3d_device_context_set_stream_source(ptr long ptr) +@ cdecl wined3d_device_context_set_stream_sources(ptr long long ptr) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_context_set_viewports(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7ca6a8d7e2e..3e87aa94761 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4818,8 +4818,8 @@ void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device struct wined3d_shader_resource_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - const struct wined3d_stream_state *state) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 000423139d0..cf26cd7a96d 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2529,8 +2529,8 @@ void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_dev void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state); void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); -HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, const struct wined3d_stream_state *stream); +HRESULT __cdecl wined3d_device_context_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 17 ++++- dlls/d3d11/tests/d3d11.c | 30 ++++----- dlls/wined3d/cs.c | 109 +++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 8 +++ dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 2 + include/wine/wined3d.h | 2 + 7 files changed, 150 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index e832d8e68d3..b6e60050f4f 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -447,6 +447,14 @@ static const struct ID3D11CommandListVtbl d3d11_command_list_vtbl = d3d11_command_list_GetContextFlags, };
+static struct d3d11_command_list *unsafe_impl_from_ID3D11CommandList(ID3D11CommandList *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d11_command_list_vtbl); + return impl_from_ID3D11CommandList(iface); +} + /* ID3D11DeviceContext - immediate context methods */
static inline struct d3d11_device_context *impl_from_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) @@ -1513,7 +1521,14 @@ static void STDMETHODCALLTYPE d3d11_device_context_ResolveSubresource(ID3D11Devi static void STDMETHODCALLTYPE d3d11_device_context_ExecuteCommandList(ID3D11DeviceContext1 *iface, ID3D11CommandList *command_list, BOOL restore_state) { - FIXME("iface %p, command_list %p, restore_state %#x stub!\n", iface, command_list, restore_state); + struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); + struct d3d11_command_list *list_impl = unsafe_impl_from_ID3D11CommandList(command_list); + + TRACE("iface %p, command_list %p, restore_state %#x.\n", iface, command_list, restore_state); + + wined3d_mutex_lock(); + wined3d_device_context_execute_command_list(context->wined3d_context, list_impl->wined3d_list, !!restore_state); + wined3d_mutex_unlock(); }
static void STDMETHODCALLTYPE d3d11_device_context_HSSetShaderResources(ID3D11DeviceContext1 *iface, diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 8da0cfaa8bf..408c0492cd2 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -32302,9 +32302,7 @@ static void test_deferred_context_state(void) ID3D11DeviceContext_PSSetConstantBuffers(immediate, 0, 1, &green_buffer); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, FALSE); ID3D11DeviceContext_PSGetConstantBuffers(immediate, 0, 1, &ret_buffer); - todo_wine ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer); - if (ret_buffer) - ID3D11Buffer_Release(ret_buffer); + ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer);
ID3D11CommandList_Release(list2); ID3D11CommandList_Release(list1); @@ -32328,9 +32326,7 @@ static void test_deferred_context_state(void) ID3D11DeviceContext_PSSetConstantBuffers(deferred, 0, 1, &blue_buffer); ID3D11DeviceContext_ExecuteCommandList(deferred, list1, FALSE); ID3D11DeviceContext_PSGetConstantBuffers(deferred, 0, 1, &ret_buffer); - todo_wine ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer); - if (ret_buffer) - ID3D11Buffer_Release(ret_buffer); + ok(!ret_buffer, "Got unexpected buffer %p.\n", ret_buffer);
ID3D11CommandList_Release(list1); ID3D11DeviceContext_Release(deferred2); @@ -32488,12 +32484,12 @@ static void test_deferred_context_rendering(void)
ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, TRUE); @@ -32509,7 +32505,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(immediate, test_context.backbuffer_rtv, &white.x); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list2); ID3D11CommandList_Release(list1); @@ -32535,7 +32531,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_ClearRenderTargetView(immediate, rtv, blue); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, TRUE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xffff0000, "Got unexpected color %#08x.\n", color); + ok(color == 0xffff0000, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list1); ID3D11DeviceContext_Release(deferred); @@ -32569,12 +32565,10 @@ static void test_deferred_context_rendering(void) set_viewport(immediate, 0.0f, 0.0f, 640.0f, 480.0f, 0.0f, 1.0f); draw_color_quad(&test_context, &white); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color); + ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color);
ID3D11DeviceContext_OMGetBlendState(immediate, &ret_blend, blend_factor, &sample_mask); - todo_wine ok(!ret_blend, "Got unexpected blend state %p.\n", ret_blend); - if (ret_blend) - ID3D11BlendState_Release(ret_blend); + ok(!ret_blend, "Got unexpected blend state %p.\n", ret_blend);
ID3D11CommandList_Release(list1); ID3D11DeviceContext_Release(deferred); @@ -32602,7 +32596,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_OMSetBlendState(immediate, red_blend, NULL, D3D11_DEFAULT_SAMPLE_MASK); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, FALSE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color); + ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list1);
@@ -32625,7 +32619,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_OMSetBlendState(immediate, red_blend, NULL, D3D11_DEFAULT_SAMPLE_MASK); ID3D11DeviceContext_ExecuteCommandList(immediate, list1, FALSE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list1);
@@ -32658,7 +32652,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_OMSetBlendState(immediate, red_blend, NULL, D3D11_DEFAULT_SAMPLE_MASK); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, FALSE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color); + ok(color == 0xffffffff, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list2);
@@ -32678,7 +32672,7 @@ static void test_deferred_context_rendering(void) ID3D11DeviceContext_OMSetBlendState(immediate, red_blend, NULL, D3D11_DEFAULT_SAMPLE_MASK); ID3D11DeviceContext_ExecuteCommandList(immediate, list2, FALSE); color = get_texture_color(test_context.backbuffer, 320, 240); - todo_wine ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color); + ok(color == 0xff00ff00, "Got unexpected color %#08x.\n", color);
ID3D11CommandList_Release(list2);
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 1e082ce724d..50a08334dab 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -37,6 +37,12 @@ struct wined3d_command_list
SIZE_T resource_count; struct wined3d_resource **resources; + + /* List of command lists queued for execution on this command list. We might + * be the only thing holding a pointer to another command list, so we need + * to hold a reference here (and in wined3d_deferred_context) as well. */ + SIZE_T command_list_count; + struct wined3d_command_list **command_lists; };
static void wined3d_command_list_destroy_object(void *object) @@ -70,6 +76,8 @@ ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list) { SIZE_T i;
+ for (i = 0; i < list->command_list_count; ++i) + wined3d_command_list_decref(list->command_lists[i]); for (i = 0; i < list->resource_count; ++i) wined3d_resource_decref(list->resources[i]);
@@ -130,6 +138,7 @@ enum wined3d_cs_op WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_COPY_UAV_COUNTER, WINED3D_CS_OP_GENERATE_MIPMAPS, + WINED3D_CS_OP_EXECUTE_COMMAND_LIST, WINED3D_CS_OP_STOP, };
@@ -511,6 +520,12 @@ struct wined3d_cs_generate_mipmaps struct wined3d_shader_resource_view *view; };
+struct wined3d_cs_execute_command_list +{ + enum wined3d_cs_op opcode; + struct wined3d_command_list *list; +}; + struct wined3d_cs_stop { enum wined3d_cs_op opcode; @@ -599,6 +614,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_COPY_UAV_COUNTER); WINED3D_TO_STR(WINED3D_CS_OP_GENERATE_MIPMAPS); + WINED3D_TO_STR(WINED3D_CS_OP_EXECUTE_COMMAND_LIST); WINED3D_TO_STR(WINED3D_CS_OP_STOP); #undef WINED3D_TO_STR } @@ -2314,6 +2330,27 @@ static void wined3d_cs_issue_query(struct wined3d_device_context *context, query->state = QUERY_SIGNALLED; }
+static void wined3d_cs_execute_command_list(struct wined3d_device_context *context, + struct wined3d_command_list *list, bool restore_state) +{ + struct wined3d_cs_execute_command_list *op; + SIZE_T i; + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_EXECUTE_COMMAND_LIST; + op->list = list; + + for (i = 0; i < list->resource_count; ++i) + wined3d_resource_acquire(list->resources[i]); + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); + + if (restore_state) + wined3d_device_context_set_state(context, context->state); + else + wined3d_device_context_reset_state(context); +} + static void wined3d_cs_exec_preload_resource(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_preload_resource *op = data; @@ -2777,6 +2814,8 @@ static void wined3d_cs_acquire_resource(struct wined3d_device_context *context, wined3d_resource_acquire(resource); }
+static void wined3d_cs_exec_execute_command_list(struct wined3d_cs *cs, const void *data); + static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = { /* WINED3D_CS_OP_NOP */ wined3d_cs_exec_nop, @@ -2828,8 +2867,32 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view, /* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter, /* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps, + /* WINED3D_CS_OP_EXECUTE_COMMAND_LIST */ wined3d_cs_exec_execute_command_list, };
+static void wined3d_cs_exec_execute_command_list(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_execute_command_list *op = data; + size_t start = 0, end = op->list->data_size; + const BYTE *cs_data = op->list->data; + + TRACE("Executing command list %p.\n", op->list); + + while (start < end) + { + const struct wined3d_cs_packet *packet = (const struct wined3d_cs_packet *)&cs_data[start]; + enum wined3d_cs_op opcode = *(const enum wined3d_cs_op *)packet->data; + + if (opcode >= WINED3D_CS_OP_STOP) + ERR("Invalid opcode %#x.\n", opcode); + else + wined3d_cs_op_handlers[opcode](cs, packet->data); + TRACE("%s executed.\n", debug_cs_op(opcode)); + + start += offsetof(struct wined3d_cs_packet, data[packet->size]); + } +} + static void *wined3d_cs_st_require_space(struct wined3d_device_context *context, size_t size, enum wined3d_cs_queue_id queue_id) { @@ -2897,6 +2960,7 @@ static const struct wined3d_device_context_ops wined3d_cs_st_ops = wined3d_cs_issue_query, wined3d_cs_flush, wined3d_cs_acquire_resource, + wined3d_cs_execute_command_list, };
static BOOL wined3d_cs_queue_is_empty(const struct wined3d_cs *cs, const struct wined3d_cs_queue *queue) @@ -3024,6 +3088,7 @@ static const struct wined3d_device_context_ops wined3d_cs_mt_ops = wined3d_cs_issue_query, wined3d_cs_flush, wined3d_cs_acquire_resource, + wined3d_cs_execute_command_list, };
static void poll_queries(struct wined3d_cs *cs) @@ -3235,6 +3300,12 @@ struct wined3d_deferred_context
SIZE_T resource_count, resources_capacity; struct wined3d_resource **resources; + + /* List of command lists queued for execution on this context. A command + * list can be the only thing holding a pointer to another command list, so + * we need to hold a reference here and in wined3d_command_list as well. */ + SIZE_T command_list_count, command_lists_capacity; + struct wined3d_command_list **command_lists; };
static struct wined3d_deferred_context *wined3d_deferred_context_from_context(struct wined3d_device_context *context) @@ -3332,6 +3403,30 @@ static void wined3d_deferred_context_acquire_resource(struct wined3d_device_cont wined3d_resource_incref(resource); }
+static void wined3d_deferred_context_execute_command_list(struct wined3d_device_context *context, + struct wined3d_command_list *list, bool restore_state) +{ + struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context); + struct wined3d_cs_execute_command_list *op; + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_EXECUTE_COMMAND_LIST; + op->list = list; + + if (restore_state) + wined3d_device_context_set_state(context, context->state); + else + wined3d_device_context_reset_state(context); + + /* Grab a reference to the command list. Note that this implicitly prevents + * any dependent command lists or resources from being freed as well. */ + if (!wined3d_array_reserve((void **)&deferred->command_lists, &deferred->command_lists_capacity, + deferred->command_list_count + 1, sizeof(*deferred->command_lists))) + return; + + wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list); +} + static const struct wined3d_device_context_ops wined3d_deferred_context_ops = { wined3d_deferred_context_require_space, @@ -3344,6 +3439,7 @@ static const struct wined3d_device_context_ops wined3d_deferred_context_ops = wined3d_deferred_context_issue_query, wined3d_deferred_context_flush, wined3d_deferred_context_acquire_resource, + wined3d_deferred_context_execute_command_list, };
HRESULT CDECL wined3d_deferred_context_create(struct wined3d_device *device, struct wined3d_device_context **context) @@ -3419,8 +3515,21 @@ HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device memcpy(object->resources, deferred->resources, deferred->resource_count * sizeof(*object->resources)); /* Transfer our references to the resources to the command list. */
+ if (!(object->command_lists = heap_alloc(deferred->command_list_count * sizeof(*object->command_lists)))) + { + heap_free(object->resources); + heap_free(object->data); + heap_free(object); + return E_OUTOFMEMORY; + } + object->command_list_count = deferred->command_list_count; + memcpy(object->command_lists, deferred->command_lists, + deferred->command_list_count * sizeof(*object->command_lists)); + /* Transfer our references to the command lists to the command list. */ + deferred->data_size = 0; deferred->resource_count = 0; + deferred->command_list_count = 0;
/* This is in fact recorded into a subsequent command list. */ if (restore) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 08f986dd5e2..c6b0c9f831e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4888,6 +4888,14 @@ void CDECL wined3d_device_context_issue_query(struct wined3d_device_context *con context->ops->issue_query(context, query, flags); }
+void CDECL wined3d_device_context_execute_command_list(struct wined3d_device_context *context, + struct wined3d_command_list *list, bool restore_state) +{ + TRACE("context %p, list %p, restore_state %d.\n", context, list, restore_state); + + context->ops->execute_command_list(context, list, restore_state); +} + struct wined3d_rendertarget_view * CDECL wined3d_device_context_get_rendertarget_view( const struct wined3d_device_context *context, unsigned int view_idx) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 6683b3bc30f..1369fd4cf90 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -95,6 +95,7 @@ @ cdecl wined3d_device_context_draw_indirect(ptr ptr long long) @ cdecl wined3d_device_context_dispatch(ptr long long long) @ cdecl wined3d_device_context_dispatch_indirect(ptr ptr long) +@ cdecl wined3d_device_context_execute_command_list(ptr ptr long) @ cdecl wined3d_device_context_flush(ptr) @ cdecl wined3d_device_context_generate_mipmaps(ptr ptr) @ cdecl wined3d_device_context_get_blend_state(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index af9beffc142..8e3efccffc2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4693,6 +4693,8 @@ struct wined3d_device_context_ops void (*issue_query)(struct wined3d_device_context *context, struct wined3d_query *query, unsigned int flags); void (*flush)(struct wined3d_device_context *context); void (*acquire_resource)(struct wined3d_device_context *context, struct wined3d_resource *resource); + void (*execute_command_list)(struct wined3d_device_context *context, + struct wined3d_command_list *list, bool restore_state); };
struct wined3d_device_context diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index bb6bf58a822..7777e45ad21 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2441,6 +2441,8 @@ void __cdecl wined3d_device_context_draw_indexed(struct wined3d_device_context * unsigned int start_index, unsigned int index_count, unsigned int start_instance, unsigned int instance_count); void __cdecl wined3d_device_context_draw_indirect(struct wined3d_device_context *context, struct wined3d_buffer *buffer, unsigned int offset, bool indexed); +void __cdecl wined3d_device_context_execute_command_list(struct wined3d_device_context *context, + struct wined3d_command_list *list, bool restore_state); void __cdecl wined3d_device_context_flush(struct wined3d_device_context *context); void __cdecl wined3d_device_context_generate_mipmaps(struct wined3d_device_context *context, struct wined3d_shader_resource_view *view);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 27 +++++----- dlls/d3d8/device.c | 3 +- dlls/d3d9/device.c | 2 +- dlls/ddraw/ddraw.c | 2 +- dlls/ddraw/device.c | 13 +++-- dlls/ddraw/surface.c | 7 +-- dlls/wined3d/cs.c | 78 ++++++++++++++++------------- dlls/wined3d/device.c | 91 +++++++++++++++++----------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +- include/wine/wined3d.h | 4 +- 11 files changed, 123 insertions(+), 110 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 33aa098152d..b91583964ed 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1056,6 +1056,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargets(ID3D11Devi UINT render_target_view_count, ID3D11RenderTargetView *const *render_target_views, ID3D11DepthStencilView *depth_stencil_view) { + struct wined3d_rendertarget_view *wined3d_rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); struct d3d_depthstencil_view *dsv; unsigned int i; @@ -1063,19 +1064,18 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargets(ID3D11Devi TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", iface, render_target_view_count, render_target_views, depth_stencil_view);
- wined3d_mutex_lock(); for (i = 0; i < render_target_view_count; ++i) { struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D11RenderTargetView(render_target_views[i]); - wined3d_device_context_set_rendertarget_view(context->wined3d_context, i, - rtv ? rtv->wined3d_view : NULL, FALSE); - } - for (; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) - { - wined3d_device_context_set_rendertarget_view(context->wined3d_context, i, NULL, FALSE); + + wined3d_rtvs[i] = rtv ? rtv->wined3d_view : NULL; }
dsv = unsafe_impl_from_ID3D11DepthStencilView(depth_stencil_view); + + wined3d_mutex_lock(); + wined3d_device_context_set_rendertarget_views(context->wined3d_context, 0, + ARRAY_SIZE(wined3d_rtvs), wined3d_rtvs, FALSE); wined3d_device_context_set_depth_stencil_view(context->wined3d_context, dsv ? dsv->wined3d_view : NULL); wined3d_mutex_unlock(); } @@ -4849,6 +4849,7 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *ifa UINT render_target_view_count, ID3D10RenderTargetView *const *render_target_views, ID3D10DepthStencilView *depth_stencil_view) { + struct wined3d_rendertarget_view *wined3d_rtvs[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; struct d3d_device *device = impl_from_ID3D10Device(iface); struct d3d_depthstencil_view *dsv; unsigned int i; @@ -4856,20 +4857,18 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *ifa TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", iface, render_target_view_count, render_target_views, depth_stencil_view);
- wined3d_mutex_lock(); for (i = 0; i < render_target_view_count; ++i) { struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D10RenderTargetView(render_target_views[i]);
- wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, - rtv ? rtv->wined3d_view : NULL, FALSE); - } - for (; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) - { - wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, NULL, FALSE); + wined3d_rtvs[i] = rtv ? rtv->wined3d_view : NULL; }
dsv = unsafe_impl_from_ID3D10DepthStencilView(depth_stencil_view); + + wined3d_mutex_lock(); + wined3d_device_context_set_rendertarget_views(device->immediate_context.wined3d_context, 0, + ARRAY_SIZE(wined3d_rtvs), wined3d_rtvs, FALSE); wined3d_device_context_set_depth_stencil_view(device->immediate_context.wined3d_context, dsv ? dsv->wined3d_view : NULL); wined3d_mutex_unlock(); diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index b14e6679763..84aefef9a56 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1544,7 +1544,8 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; if (render_target) { - if (SUCCEEDED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, 0, rtv, TRUE))) + if (SUCCEEDED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, + 0, 1, &rtv, TRUE))) device_reset_viewport_state(device); else wined3d_device_context_set_depth_stencil_view(device->immediate_context, original_dsv); diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 932d6d2d814..fed461458d2 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -2028,7 +2028,7 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
wined3d_mutex_lock(); rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; - hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, idx, rtv, TRUE); + hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, idx, 1, &rtv, TRUE); d3d9_surface_release_rendertarget_view(surface_impl, rtv); if (SUCCEEDED(hr)) { diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 972c18fbfe9..5b70bb4f86d 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -958,7 +958,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (rtv) { - wined3d_device_context_set_rendertarget_view(ddraw->immediate_context, 0, rtv, FALSE); + wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &rtv, FALSE); wined3d_rendertarget_view_decref(rtv); }
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index e9070cfbda6..a56d2e62295 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -270,6 +270,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) * wined3d device when the render target is released. */ if (!ref) { + static struct wined3d_rendertarget_view *const null_rtv; DWORD i; struct list *vp_entry, *vp_entry2;
@@ -283,7 +284,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) if (This->vertex_buffer) wined3d_buffer_decref(This->vertex_buffer);
- wined3d_device_context_set_rendertarget_view(This->immediate_context, 0, NULL, FALSE); + wined3d_device_context_set_rendertarget_views(This->immediate_context, 0, 1, &null_rtv, FALSE);
wined3d_stateblock_decref(This->state); if (This->recording) @@ -1848,6 +1849,7 @@ static BOOL validate_surface_palette(struct ddraw_surface *surface) static HRESULT d3d_device_set_render_target(struct d3d_device *device, struct ddraw_surface *target, IUnknown *rt_iface) { + struct wined3d_rendertarget_view *rtv; HRESULT hr;
if (device->rt_iface == rt_iface) @@ -1861,8 +1863,8 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device, return DDERR_INVALIDPARAMS; }
- if (FAILED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, - 0, ddraw_surface_get_rendertarget_view(target), FALSE))) + rtv = ddraw_surface_get_rendertarget_view(target); + if (FAILED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, FALSE))) return hr;
IUnknown_AddRef(rt_iface); @@ -6994,6 +6996,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; + struct wined3d_rendertarget_view *rtv; HRESULT hr;
if (ddraw->cooperative_level & DDSCL_FPUPRESERVE) @@ -7043,8 +7046,8 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c wined3d_stateblock_incref(ddraw->state);
/* Render to the back buffer */ - if (FAILED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, - 0, ddraw_surface_get_rendertarget_view(target), TRUE))) + rtv = ddraw_surface_get_rendertarget_view(target); + if (FAILED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, TRUE))) { ERR("Failed to set render target, hr %#x.\n", hr); wined3d_stateblock_decref(device->state); diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 7834d9c943b..25aa2be41bb 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1369,7 +1369,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *
src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, src_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); @@ -1406,7 +1406,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * src_impl = impl_from_IDirectDrawSurface(current); src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, src_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, + 0, 1, &src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); @@ -1429,7 +1430,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * /* We don't have to worry about potential texture bindings, since * flippable surfaces can never be textures. */ if (rtv == src_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, tmp_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &tmp_rtv, FALSE); wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); src_impl->wined3d_rtv = tmp_rtv; wined3d_texture_set_sub_resource_parent(texture, 0, src_impl); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 3ee6c255e67..dc32fe7f9d9 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -109,7 +109,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_PREDICATION, WINED3D_CS_OP_SET_VIEWPORTS, WINED3D_CS_OP_SET_SCISSOR_RECTS, - WINED3D_CS_OP_SET_RENDERTARGET_VIEW, + WINED3D_CS_OP_SET_RENDERTARGET_VIEWS, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCES, @@ -229,11 +229,12 @@ struct wined3d_cs_set_scissor_rects RECT rects[1]; };
-struct wined3d_cs_set_rendertarget_view +struct wined3d_cs_set_rendertarget_views { enum wined3d_cs_op opcode; - unsigned int view_idx; - struct wined3d_rendertarget_view *view; + unsigned int start_idx; + unsigned int count; + struct wined3d_rendertarget_view *views[1]; };
struct wined3d_cs_set_depth_stencil_view @@ -591,7 +592,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_PREDICATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_VIEWPORTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_SCISSOR_RECTS); - WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEWS); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCES); @@ -1295,43 +1296,50 @@ void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_rendertarget_views(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_rendertarget_view *op = data; - bool prev_alpha_swizzle, curr_alpha_swizzle; - struct wined3d_rendertarget_view *prev; - bool prev_srgb_write, curr_srgb_write; - struct wined3d_device *device; + const struct wined3d_cs_set_rendertarget_views *op = data; + struct wined3d_device *device = cs->c.device; + unsigned int i;
- device = cs->c.device; - prev = cs->state.fb.render_targets[op->view_idx]; - cs->state.fb.render_targets[op->view_idx] = op->view; - device_invalidate_state(device, STATE_FRAMEBUFFER); - - prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; - curr_alpha_swizzle = op->view && op->view->format->id == WINED3DFMT_A8_UNORM; - if (prev_alpha_swizzle != curr_alpha_swizzle) - device_invalidate_state(device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); - - if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) - || cs->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) + for (i = 0; i < op->count; ++i) { - prev_srgb_write = prev && prev->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; - curr_srgb_write = op->view && op->view->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; - if (prev_srgb_write != curr_srgb_write) - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + struct wined3d_rendertarget_view *prev = cs->state.fb.render_targets[op->start_idx + i]; + struct wined3d_rendertarget_view *view = op->views[i]; + bool prev_alpha_swizzle, curr_alpha_swizzle; + bool prev_srgb_write, curr_srgb_write; + + cs->state.fb.render_targets[op->start_idx + i] = view; + + prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; + curr_alpha_swizzle = view && view->format->id == WINED3DFMT_A8_UNORM; + if (prev_alpha_swizzle != curr_alpha_swizzle) + device_invalidate_state(device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); + + if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) + || cs->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) + { + prev_srgb_write = prev && prev->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; + curr_srgb_write = view && view->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; + if (prev_srgb_write != curr_srgb_write) + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + } } + + device_invalidate_state(device, STATE_FRAMEBUFFER); }
-void wined3d_device_context_emit_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, - struct wined3d_rendertarget_view *view) +void wined3d_device_context_emit_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views) { - struct wined3d_cs_set_rendertarget_view *op; + struct wined3d_cs_set_rendertarget_views *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; - op->view_idx = view_idx; - op->view = view; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_rendertarget_views, views[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEWS; + op->start_idx = start_idx; + op->count = count; + memcpy(op->views, views, count * sizeof(*views));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2905,7 +2913,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, /* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports, /* WINED3D_CS_OP_SET_SCISSOR_RECTS */ wined3d_cs_exec_set_scissor_rects, - /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, + /* WINED3D_CS_OP_SET_RENDERTARGET_VIEWS */ wined3d_cs_exec_set_rendertarget_views, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCES */ wined3d_cs_exec_set_stream_sources, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8dcf5ffdfe6..3a3fec3d889 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -932,16 +932,14 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device *device)
static void device_init_swapchain_state(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { + struct wined3d_rendertarget_view *views[WINED3D_MAX_RENDER_TARGETS] = {0}; BOOL ds_enable = swapchain->state.desc.enable_auto_depth_stencil; struct wined3d_device_context *context = &device->cs->c; - unsigned int i;
- for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) - { - wined3d_device_context_set_rendertarget_view(context, i, NULL, FALSE); - } if (device->back_buffer_view) - wined3d_device_context_set_rendertarget_view(context, 0, device->back_buffer_view, TRUE); + views[0] = device->back_buffer_view; + wined3d_device_context_set_rendertarget_views(context, 0, + device->adapter->d3d_info.limits.max_rt_count, views, !!device->back_buffer_view);
wined3d_device_context_set_depth_stencil_view(context, ds_enable ? device->auto_depth_stencil_view : NULL); } @@ -1651,10 +1649,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte context->state = state; wined3d_device_context_emit_set_feature_level(context, state->feature_level);
- for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) - { - wined3d_device_context_emit_set_rendertarget_view(context, i, state->fb.render_targets[i]); - } + wined3d_device_context_emit_set_rendertarget_views(context, 0, + ARRAY_SIZE(state->fb.render_targets), state->fb.render_targets);
wined3d_device_context_emit_set_depth_stencil_view(context, state->fb.depth_stencil); wined3d_device_context_emit_set_vertex_declaration(context, state->vertex_declaration); @@ -2097,68 +2093,75 @@ static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_cont } }
-HRESULT CDECL wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) +HRESULT CDECL wined3d_device_context_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views, BOOL set_viewport) { struct wined3d_state *state = context->state; - struct wined3d_rendertarget_view *prev; - unsigned int max_rt_count; + unsigned int i, max_rt_count;
- TRACE("context %p, view_idx %u, view %p, set_viewport %#x.\n", - context, view_idx, view, set_viewport); + TRACE("context %p, start_idx %u, count %u, views %p, set_viewport %#x.\n", + context, start_idx, count, views, set_viewport);
max_rt_count = context->device->adapter->d3d_info.limits.max_rt_count; - if (view_idx >= max_rt_count) + if (start_idx + count > max_rt_count) { WARN("Only %u render targets are supported.\n", max_rt_count); return WINED3DERR_INVALIDCALL; }
- if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) + for (i = 0; i < count; ++i) { - WARN("View resource %p doesn't have render target bind flags.\n", view->resource); - return WINED3DERR_INVALIDCALL; + if (views[i] && !(views[i]->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) + { + WARN("View resource %p doesn't have render target bind flags.\n", views[i]->resource); + return WINED3DERR_INVALIDCALL; + } }
/* Set the viewport and scissor rectangles, if requested. Tests show that * stateblock recording is ignored, the change goes directly into the * primary stateblock. */ - if (!view_idx && set_viewport) + if (!start_idx && set_viewport) { state->viewports[0].x = 0; state->viewports[0].y = 0; - state->viewports[0].width = view->width; - state->viewports[0].height = view->height; + state->viewports[0].width = views[0]->width; + state->viewports[0].height = views[0]->height; state->viewports[0].min_z = 0.0f; state->viewports[0].max_z = 1.0f; state->viewport_count = 1; wined3d_device_context_emit_set_viewports(context, 1, state->viewports);
- SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); + SetRect(&state->scissor_rects[0], 0, 0, views[0]->width, views[0]->height); state->scissor_rect_count = 1; wined3d_device_context_emit_set_scissor_rects(context, 1, state->scissor_rects); }
- prev = state->fb.render_targets[view_idx]; - if (view == prev) + if (!memcmp(views, &state->fb.render_targets[start_idx], count * sizeof(*views))) return WINED3D_OK;
- if (view) + wined3d_device_context_emit_set_rendertarget_views(context, start_idx, count, views); + for (i = 0; i < count; ++i) { - wined3d_rendertarget_view_incref(view); - wined3d_rtv_bind_count_inc(view); - } - state->fb.render_targets[view_idx] = view; - wined3d_device_context_emit_set_rendertarget_view(context, view_idx, view); - /* Release after the assignment, to prevent device_resource_released() - * from seeing the surface as still in use. */ - if (prev) - { - wined3d_rtv_bind_count_dec(prev); - wined3d_rendertarget_view_decref(prev); - } + struct wined3d_rendertarget_view *prev = state->fb.render_targets[start_idx + i]; + struct wined3d_rendertarget_view *view = views[i];
- wined3d_device_context_unbind_srv_for_rtv(context, view, FALSE); + if (view) + { + wined3d_rendertarget_view_incref(view); + wined3d_rtv_bind_count_inc(view); + } + state->fb.render_targets[start_idx + i] = view; + /* Release after the assignment, to prevent device_resource_released() + * from seeing the surface as still in use. */ + if (prev) + { + wined3d_rtv_bind_count_dec(prev); + wined3d_rendertarget_view_decref(prev); + } + + wined3d_device_context_unbind_srv_for_rtv(context, view, FALSE); + }
return WINED3D_OK; } @@ -5173,6 +5176,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state) { + static struct wined3d_rendertarget_view *const views[WINED3D_MAX_RENDER_TARGETS]; const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_device_context *context = &device->cs->c; struct wined3d_swapchain_state *swapchain_state; @@ -5214,10 +5218,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state_unbind_resources(state); }
- for (i = 0; i < d3d_info->limits.max_rt_count; ++i) - { - wined3d_device_context_set_rendertarget_view(context, i, NULL, FALSE); - } + wined3d_device_context_set_rendertarget_views(context, 0, d3d_info->limits.max_rt_count, views, FALSE); wined3d_device_context_set_depth_stencil_view(context, NULL);
if (reset_state) @@ -5440,7 +5441,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, else { if ((view = device->back_buffer_view)) - wined3d_device_context_set_rendertarget_view(context, 0, view, FALSE); + wined3d_device_context_set_rendertarget_views(context, 0, 1, &view, FALSE); if ((view = device->auto_depth_stencil_view)) wined3d_device_context_set_depth_stencil_view(context, view); } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index bcdeb38b96b..37c3d615433 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -129,7 +129,7 @@ @ cdecl wined3d_device_context_set_predication(ptr ptr long) @ cdecl wined3d_device_context_set_primitive_type(ptr long long) @ cdecl wined3d_device_context_set_rasterizer_state(ptr ptr) -@ cdecl wined3d_device_context_set_rendertarget_view(ptr long ptr long) +@ cdecl wined3d_device_context_set_rendertarget_views(ptr long long ptr long) @ cdecl wined3d_device_context_set_samplers(ptr long long long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3e87aa94761..0e55cb2e67b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4803,8 +4803,8 @@ void wined3d_device_context_emit_set_rasterizer_state(struct wined3d_device_cont struct wined3d_rasterizer_state *rasterizer_state) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_render_state(struct wined3d_device_context *context, enum wined3d_render_state state, unsigned int value) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, - struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_rendertarget_views(struct wined3d_device_context *context, unsigned int start_idx, + unsigned int count, struct wined3d_rendertarget_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_sampler_state(struct wined3d_device_context *context, unsigned int sampler_idx, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index cf26cd7a96d..c77e1a6c79c 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2515,8 +2515,8 @@ void __cdecl wined3d_device_context_set_primitive_type(struct wined3d_device_con enum wined3d_primitive_type primitive_topology, unsigned int patch_vertex_count); void __cdecl wined3d_device_context_set_rasterizer_state(struct wined3d_device_context *context, struct wined3d_rasterizer_state *rasterizer_state); -HRESULT __cdecl wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); +HRESULT __cdecl wined3d_device_context_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views, BOOL set_viewport); void __cdecl wined3d_device_context_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers); void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_context *context, unsigned int rect_count,
On Thu, 27 May 2021 at 04:15, Zebediah Figura z.figura12@gmail.com wrote:
+void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_buffer *const *buffers)
{ struct wined3d_state *state = context->state;
- struct wined3d_buffer *prev;
- unsigned int i;
- TRACE("context %p, type %#x, idx %u, buffer %p.\n", context, type, idx, buffer);
- TRACE("context %p, type %#x, start_idx %u, count %u, buffers %p.\n", context, type, start_idx, count, buffers);
- if (idx >= MAX_CONSTANT_BUFFERS)
- if (start_idx + count > MAX_CONSTANT_BUFFERS) {
WARN("Invalid constant buffer index %u.\n", idx);
}WARN("Invalid constant buffer index %u, count %u.\n", start_idx, count); return;
"start_idx + count" can overflow. Consider e.g. "start_idx == ~0u, count = 8;". We typically write such bound checks as "if (start_idx >= MAX_CONSTANT_BUFFERS || count > MAX_CONSTANT_BUFFERS - start_idx)". We could conceivably also use something like gcc's __builtin_uadd_overflow().