Avoid storing pointers to the CS data inside individual ops.
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 | 147 +++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 3 + include/wine/wined3d.h | 3 + 6 files changed, 250 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..9a143b915ed 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3162,3 +3162,150 @@ 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 %p, data %p, row_pitch %u, slice_pitch %u, stub!\n", + context, resource, sub_resource_idx, 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", context); + *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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91230
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:5657: Test failed: Got unexpected query result 0x0000000000000000.
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== debiant2 (32 bit French report) ===
d3d11: d3d11.c:9660: Test failed: d3d11.c:15112: Test marked todo: Got hr 0 for WRITE_NO_OVERWRITE. d3d11.c:9660: Test failed: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE.
=== debiant2 (32 bit Hindi:India report) ===
d3d11: d3d11.c:9660: Test failed: Got hr 0 for WRITE_DISCARD.
=== debiant2 (32 bit Chinese:China report) ===
d3d11: d3d11.c:19759: Test failed: d3d11.c:16301: Test marked todo: Got 0xdeadbeef, expected 0x80706050 or 0x7f7f7f7f at 127, uvec4 0x7fffff50, 0x7fffff60, 0x7fffff70, 0x7fffff80.
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
+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 %p, data %p, row_pitch %u, slice_pitch %u, stub!\n",
context, resource, sub_resource_idx, box, data, row_pitch, slice_pitch);
+}
"debug_box(box)", probably.
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 +---- dlls/wined3d/cs.c | 2 +- 3 files changed, 12 insertions(+), 7 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); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 9a143b915ed..e903b94378e 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3293,7 +3293,7 @@ HRESULT CDECL wined3d_deferred_context_create(struct wined3d_device *device, str object->c.ops = &wined3d_deferred_context_ops; object->c.device = device;
- TRACE("Created deferred context %p.\n", context); + TRACE("Created deferred context %p.\n", object); *context = &object->c;
return S_OK;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91231
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0. d3d11.c:5657: Test failed: Got unexpected query result 0x0000000000000000.
=== debiant2 (32 bit Japanese:Japan report) ===
d3d11: d3d11.c:9660: Test failed: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE.
=== debiant2 (32 bit Chinese:China report) ===
d3d11: d3d11.c:5833: Test failed: d3d11.c:6153: Test marked todo: Got unexpected PrimitivesStorageNeeded: 2.
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
@@ -3293,7 +3293,7 @@ HRESULT CDECL wined3d_deferred_context_create(struct wined3d_device *device, str object->c.ops = &wined3d_deferred_context_ops; object->c.device = device;
- TRACE("Created deferred context %p.\n", context);
- TRACE("Created deferred context %p.\n", object);
That belongs in 2/8.
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 e903b94378e..e1ffd8f0ff8 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) @@ -3257,7 +3260,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 = @@ -3302,9 +3312,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);
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 e1ffd8f0ff8..42f7606d3c9 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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91233
Your paranoid android.
=== debiant2 (32 bit report) ===
d3d11: d3d11.c:9660: Test failed: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE. d3d11.c:9660: Test failed: d3d11.c:15112: Test marked todo: Got hr 0 for WRITE_DISCARD. d3d11.c:9660: Test failed: d3d11.c:15112: Test marked todo: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE.
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..f4c66ca4ce9 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; + + ID3D11Device *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..17bb0da369c 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(); + ID3D11Device_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; + ID3D11Device_AddRef(*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; + + object->ID3D11CommandList_iface.lpVtbl = &d3d11_command_list_vtbl; + object->refcount = 1; + object->device = (ID3D11Device *)&context->device->ID3D11Device2_iface; + wined3d_private_store_init(&object->private_store); + + 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; + } + + ID3D11Device2_AddRef(&context->device->ID3D11Device2_iface); + + wined3d_mutex_unlock(); + + 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 42f7606d3c9..137f979ae4a 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, @@ -3334,3 +3387,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..e4fd0b73268 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,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91234
Your paranoid android.
=== debiant2 (32 bit report) ===
d3d11: d3d11: Timeout
=== debiant2 (32 bit Chinese:China report) ===
d3d11: d3d11: Timeout
=== debiant2 (32 bit WoW report) ===
d3d11: d3d11: Timeout
=== debiant2 (64 bit WoW report) ===
d3d11: d3d11: Timeout
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
+struct d3d11_command_list +{
- ID3D11CommandList ID3D11CommandList_iface;
- LONG refcount;
- ID3D11Device *device;
- struct wined3d_command_list *wined3d_list;
- struct wined3d_private_store private_store;
+};
[...]
+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;
- ID3D11Device_AddRef(*device);
+}
The cast seems superfluous, but an argument could also be made for storing an ID3D11Device2 pointer in struct d3d11_command_list, like we do for most other d3d11 objects.
@@ -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;
- object->ID3D11CommandList_iface.lpVtbl = &d3d11_command_list_vtbl;
- object->refcount = 1;
- object->device = (ID3D11Device *)&context->device->ID3D11Device2_iface;
- wined3d_private_store_init(&object->private_store);
... in which case we could get rid of the cast above instead.
- 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;
- }
That's missing a wined3d_private_store_cleanup(), strictly speaking. It wouldn't do anything in this case, but that's an implementation detail, and subject to future change.
- ID3D11Device2_AddRef(&context->device->ID3D11Device2_iface);
That should probably be "ID3D11Device_AddRef(object->device);".
+HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device_context *context,
BOOL restore, struct wined3d_command_list **list)
+{
bool, probably.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This does take up a lot of space in the CS queue, though. It may make more sense to add another CS op instead...
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 137f979ae4a..a3b7cebce2a 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3396,12 +3396,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;
@@ -3430,7 +3424,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;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91235
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== debiant2 (32 bit Arabic:Morocco report) ===
d3d11: d3d11.c:5833: Test failed: Got unexpected hr 0x1.
=== debiant2 (32 bit Hebrew:Israel report) ===
d3d11: d3d11.c:9660: Test failed: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/d3d11/device.c | 17 ++++- dlls/d3d11/tests/d3d11.c | 30 ++++----- dlls/wined3d/cs.c | 116 +++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 8 +++ dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 2 + include/wine/wined3d.h | 2 + 7 files changed, 157 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 17bb0da369c..366bd9b2976 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 a3b7cebce2a..20b2719fa9d 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) @@ -3333,6 +3404,37 @@ 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; + 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; + + if (restore_state) + wined3d_device_context_set_state(context, context->state); + else + wined3d_device_context_reset_state(context); + + /* Grab a reference to each command list queued on this command list, as + * well as the command list itself. */ + if (!wined3d_array_reserve((void **)&deferred->command_lists, &deferred->command_lists_capacity, + deferred->command_list_count + list->command_list_count + 1, sizeof(*deferred->command_lists))) + return; + + for (i = 0; i < list->command_list_count; ++i) + wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list->command_lists[i]); + wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list); + + /* And grab a reference to each of the command list's resources. */ + for (i = 0; i < list->resource_count; ++i) + wined3d_deferred_context_acquire_resource(context, list->resources[i]); +} + static const struct wined3d_device_context_ops wined3d_deferred_context_ops = { wined3d_deferred_context_require_space, @@ -3345,6 +3447,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) @@ -3420,8 +3523,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..ff87e3526cd 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..ce93da3a81b 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 e4fd0b73268..4b22615a569 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);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=91236
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== w10pro64 (32 bit report) ===
d3d11: d3d11.c:5810: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5811: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5812: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5815: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5816: Test failed: Got unexpected CPrimitives count: 0.
=== debiant2 (32 bit Japanese:Japan report) ===
d3d11: d3d11.c:9660: Test failed: d3d11.c:15021: Test marked todo: Got hr 0 for WRITE_DISCARD.
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
+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;
- 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;
- if (restore_state)
wined3d_device_context_set_state(context, context->state);
- else
wined3d_device_context_reset_state(context);
- /* Grab a reference to each command list queued on this command list, as
* well as the command list itself. */
- if (!wined3d_array_reserve((void **)&deferred->command_lists, &deferred->command_lists_capacity,
deferred->command_list_count + list->command_list_count + 1, sizeof(*deferred->command_lists)))
return;
- for (i = 0; i < list->command_list_count; ++i)
wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list->command_lists[i]);
- wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list);
Is that really needed? Wouldn't the reference we keep to "list" already prevent anything referenced by "list" from being released?
+void CDECL wined3d_device_context_execute_command_list(struct wined3d_device_context *context,
struct wined3d_command_list *list, BOOL restore_state)
+{
bool, probably.
On 5/26/21 11:36 AM, Henri Verbeet wrote:
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
+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;
- 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;
- if (restore_state)
wined3d_device_context_set_state(context, context->state);
- else
wined3d_device_context_reset_state(context);
- /* Grab a reference to each command list queued on this command list, as
* well as the command list itself. */
- if (!wined3d_array_reserve((void **)&deferred->command_lists, &deferred->command_lists_capacity,
deferred->command_list_count + list->command_list_count + 1, sizeof(*deferred->command_lists)))
return;
- for (i = 0; i < list->command_list_count; ++i)
wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list->command_lists[i]);
- wined3d_command_list_incref(deferred->command_lists[deferred->command_list_count++] = list);
Is that really needed? Wouldn't the reference we keep to "list" already prevent anything referenced by "list" from being released?
I had to think through that for a minute, but I believe you're right.
+void CDECL wined3d_device_context_execute_command_list(struct wined3d_device_context *context,
struct wined3d_command_list *list, BOOL restore_state)
+{
bool, probably.
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
Avoid storing pointers to the CS data inside individual ops.
Why would we want to do that? My guess would be "so we can reallocate deferred context data", but then, that's just a guess.
On 5/26/21 11:34 AM, Henri Verbeet wrote:
On Wed, 26 May 2021 at 07:23, Zebediah Figura z.figura12@gmail.com wrote:
Avoid storing pointers to the CS data inside individual ops.
Why would we want to do that? My guess would be "so we can reallocate deferred context data", but then, that's just a guess.
To reallocate it, and to blit it in wined3d_deferred_context_record_command_list(), yes. I'll improve the patch message.