To support ID3D10Device interface activation on D3D11 devices.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
The idea here is only to have a minimal implementation of SwapDeviceContextState, to fix the D2D1 over D3D11 regression. What's missing is the actual state change, as well as the enabling / disabling or the D3D10 / D3D11 interface methods when state is changed to another version, as described in [1].
I didn't really investigate what the full device context state implementation would require, but I suspect it to be much bigger scope. This could possibly serve as an initial work for it as well.
[1] https://docs.microsoft.com/en-us/windows/win32/api/d3d11_1/nf-d3d11_1-id3d11...
dlls/d3d11/d3d11_main.c | 1 + dlls/d3d11/d3d11_private.h | 13 +++ dlls/d3d11/device.c | 187 ++++++++++++++++++++++++++++++++++++- dlls/d3d11/tests/d3d11.c | 38 +++++--- 4 files changed, 223 insertions(+), 16 deletions(-)
diff --git a/dlls/d3d11/d3d11_main.c b/dlls/d3d11/d3d11_main.c index dac59d09999..6666876049d 100644 --- a/dlls/d3d11/d3d11_main.c +++ b/dlls/d3d11/d3d11_main.c @@ -137,6 +137,7 @@ HRESULT WINAPI D3D11CoreCreateDevice(IDXGIFactory *factory, IDXGIAdapter *adapte return E_FAIL; } d3d_device->d3d11_only = TRUE; + d3d_device->emulated_interface = IID_ID3D11Device2;
return S_OK; } diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 3248285fcda..2effe3a8242 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -516,6 +516,18 @@ struct d3d_query *unsafe_impl_from_ID3D11Query(ID3D11Query *iface) DECLSPEC_HIDD struct d3d_query *unsafe_impl_from_ID3D10Query(ID3D10Query *iface) DECLSPEC_HIDDEN; struct d3d_query *unsafe_impl_from_ID3D11Asynchronous(ID3D11Asynchronous *iface) DECLSPEC_HIDDEN;
+/* ID3DDeviceContextState */ +struct d3d_device_context_state +{ + ID3DDeviceContextState ID3DDeviceContextState_iface; + LONG refcount; + + struct wined3d_private_store private_store; + + ID3D11Device2 *device; + GUID emulated_interface; +}; + /* ID3D11DeviceContext - immediate context */ struct d3d11_immediate_context { @@ -539,6 +551,7 @@ struct d3d_device
D3D_FEATURE_LEVEL feature_level; BOOL d3d11_only; + GUID emulated_interface;
struct d3d11_immediate_context immediate_context;
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 50e8cd58fe2..dac31913340 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -29,6 +29,140 @@ static const struct wined3d_parent_ops d3d_null_wined3d_parent_ops = d3d_null_wined3d_object_destroyed, };
+/* ID3DDeviceContextState methods */ + +static inline struct d3d_device_context_state *impl_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_device_context_state, ID3DDeviceContextState_iface); +} + +static inline struct d3d_device *device_from_ID3DDeviceContextState(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + return impl_from_ID3D11Device2(state->device); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_QueryInterface(ID3DDeviceContextState *iface, + REFIID iid, void **out) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_ID3DDeviceContextState) + || IsEqualGUID(iid, &IID_ID3D11DeviceChild) + || IsEqualGUID(iid, &IID_IUnknown)) + { + *out = &state->ID3DDeviceContextState_iface; + } + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; + } + + ID3DDeviceContextState_AddRef(iface); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE d3d_device_context_state_AddRef(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + struct d3d_device *device = device_from_ID3DDeviceContextState(iface); + ULONG refcount = InterlockedIncrement(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + + if (refcount == 1) + { + ID3D11Device2_AddRef(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d_device_context_state_Release(ID3DDeviceContextState *iface) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + struct d3d_device *device = device_from_ID3DDeviceContextState(iface); + ULONG refcount = InterlockedDecrement(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + + if (!refcount) + { + wined3d_private_store_cleanup(&state->private_store); + ID3D11Device2_Release(&device->ID3D11Device2_iface); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d_device_context_state_GetDevice(ID3DDeviceContextState *iface, ID3D11Device **device) +{ + struct d3d_device *device_object = device_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)&device_object->ID3D11Device2_iface; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_GetPrivateData(ID3DDeviceContextState *iface, REFGUID guid, + UINT *data_size, void *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_SetPrivateData(ID3DDeviceContextState *iface, REFGUID guid, + UINT data_size, const void *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&state->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d_device_context_state_SetPrivateDataInterface(ID3DDeviceContextState *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_device_context_state *state = impl_from_ID3DDeviceContextState(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&state->private_store, guid, data); +} + +static const struct ID3DDeviceContextStateVtbl d3d_device_context_state_vtbl = +{ + /* IUnknown methods */ + d3d_device_context_state_QueryInterface, + d3d_device_context_state_AddRef, + d3d_device_context_state_Release, + /* ID3D11DeviceChild methods */ + d3d_device_context_state_GetDevice, + d3d_device_context_state_GetPrivateData, + d3d_device_context_state_SetPrivateData, + d3d_device_context_state_SetPrivateDataInterface, +}; + +static void d3d_device_context_state_init(struct d3d_device_context_state *context, struct d3d_device *device, + REFIID emulated_interface) +{ + context->ID3DDeviceContextState_iface.lpVtbl = &d3d_device_context_state_vtbl; + context->refcount = 1; + context->emulated_interface = *emulated_interface; + ID3D11Device2_AddRef(context->device = &device->ID3D11Device2_iface); + + wined3d_private_store_init(&context->private_store); +} + /* ID3D11DeviceContext - immediate context methods */
static inline struct d3d11_immediate_context *impl_from_ID3D11DeviceContext1(ID3D11DeviceContext1 *iface) @@ -2551,7 +2685,33 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_CSGetConstantBuffers1(ID3D static void STDMETHODCALLTYPE d3d11_immediate_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface, ID3DDeviceContextState *state, ID3DDeviceContextState **prev_state) { - FIXME("iface %p, state %p, prev_state %p stub!\n", iface, state, prev_state); + static int once; + struct d3d_device_context_state *d3d_dc_state; + struct d3d_device *device = device_from_immediate_ID3D11DeviceContext1(iface); + + if (!once++) FIXME("iface %p, state %p, prev_state %p semi-stub!\n", iface, state, prev_state); + + if (prev_state) + { + *prev_state = NULL; + if ((d3d_dc_state = heap_alloc(sizeof(*d3d_dc_state)))) + { + d3d_device_context_state_init(d3d_dc_state, device, &device->emulated_interface); + *prev_state = &d3d_dc_state->ID3DDeviceContextState_iface; + } + } + + if (!(d3d_dc_state = impl_from_ID3DDeviceContextState(state))) + return; + + if (device->d3d11_only && + (IsEqualGUID(&d3d_dc_state->emulated_interface, &IID_ID3D10Device1) + || IsEqualGUID(&d3d_dc_state->emulated_interface, &IID_ID3D10Device))) + device->d3d11_only = FALSE; + + device->emulated_interface = d3d_dc_state->emulated_interface; + + /* FIXME: Apply device context state */ }
static void STDMETHODCALLTYPE d3d11_immediate_context_ClearView(ID3D11DeviceContext1 *iface, ID3D11View *view, @@ -3738,11 +3898,31 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateDeviceContextState(ID3D11Dev const D3D_FEATURE_LEVEL *feature_levels, UINT feature_levels_count, UINT sdk_version, REFIID emulated_interface, D3D_FEATURE_LEVEL *chosen_feature_level, ID3DDeviceContextState **state) { + struct d3d_device *device = impl_from_ID3D11Device2(iface); + struct d3d_device_context_state *d3d_device_context_state; + FIXME("iface %p, flags %#x, feature_levels %p, feature_level_count %u, sdk_version %u, " - "emulated_interface %s, chosen_feature_level %p, state %p stub!\n", iface, flags, feature_levels, + "emulated_interface %s, chosen_feature_level %p, state %p semi-stub!\n", iface, flags, feature_levels, feature_levels_count, sdk_version, debugstr_guid(emulated_interface), chosen_feature_level, state);
- return E_NOTIMPL; + if (chosen_feature_level) + *chosen_feature_level = 0; + + if (state) + { + *state = NULL; + if (!(d3d_device_context_state = heap_alloc(sizeof(*d3d_device_context_state)))) + return E_OUTOFMEMORY; + d3d_device_context_state_init(d3d_device_context_state, device, emulated_interface); + *state = &d3d_device_context_state->ID3DDeviceContextState_iface; + } + + /* FIXME: Return actual chosen feature level for the device context state */ + + if (chosen_feature_level) + *chosen_feature_level = ID3D11Device2_GetFeatureLevel(iface); + + return state ? S_OK : S_FALSE; }
static HRESULT STDMETHODCALLTYPE d3d11_device_OpenSharedResource1(ID3D11Device2 *iface, HANDLE handle, @@ -6235,6 +6415,7 @@ void d3d_device_init(struct d3d_device *device, void *outer_unknown) /* COM aggregation always takes place */ device->outer_unk = outer_unknown; device->d3d11_only = FALSE; + device->emulated_interface = GUID_NULL;
d3d11_immediate_context_init(&device->immediate_context, device); ID3D11DeviceContext1_Release(&device->immediate_context.ID3D11DeviceContext1_iface); diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 9fc09a5ec83..134902e000a 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -6686,7 +6686,6 @@ static void test_device_context_state(void) feature_level = min(feature_level, D3D_FEATURE_LEVEL_10_1); hr = ID3D11Device1_CreateDeviceContextState(device, 0, &feature_level, 1, D3D11_SDK_VERSION, &IID_ID3D10Device, NULL, &context_state); -todo_wine ok(SUCCEEDED(hr), "Failed to create device context state, hr %#x.\n", hr); if (FAILED(hr)) { @@ -6747,61 +6746,74 @@ todo_wine ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_PSGetSamplers(context, 0, 1, &tmp_sampler); - ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(tmp_sampler == (ID3D11SamplerState *)0xdeadbeef, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler && tmp_sampler != (ID3D11SamplerState *)0xdeadbeef) + ID3D11SamplerState_Release(tmp_sampler); if (!enable_debug_layer) ID3D11DeviceContext1_PSSetSamplers(context, 0, 1, &tmp_sampler);
ID3D11DeviceContext1_CSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_CSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_DSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_DSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_GSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_GSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_HSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_HSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
ID3D11DeviceContext1_VSSetSamplers(context, 0, 1, &sampler); tmp_sampler = (ID3D11SamplerState *)0xdeadbeef; ID3D11DeviceContext1_VSGetSamplers(context, 0, 1, &tmp_sampler); - ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + todo_wine ok(!tmp_sampler, "Got unexpected sampler %p.\n", tmp_sampler); + if (tmp_sampler) ID3D11SamplerState_Release(tmp_sampler);
context_type = ID3D11DeviceContext1_GetType(context); ok(context_type == D3D11_DEVICE_CONTEXT_IMMEDIATE, "Unexpected context type %u.\n", context_type);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_CSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_PSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_VSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_DSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_GSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
tmp_cb = (ID3D11Buffer *)0xdeadbeef; ID3D11DeviceContext1_HSGetConstantBuffers(context, 0, 1, &tmp_cb); - ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + todo_wine ok(!tmp_cb, "Got unexpected buffer %p.\n", tmp_cb); + if (tmp_cb) ID3D11Buffer_Release(tmp_cb);
check_interface(device, &IID_ID3D10Device, TRUE, FALSE); check_interface(device, &IID_ID3D10Device1, TRUE, FALSE);
Instead of ID2D1Factory.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d2d1/bitmap.c | 12 ++++++++---- dlls/d2d1/d2d1_private.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index 7ed57052b98..bc58d7d92d5 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -73,7 +73,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface) if (bitmap->surface) IDXGISurface_Release(bitmap->surface); ID3D10Resource_Release(bitmap->resource); - ID2D1Factory_Release(bitmap->factory); + ID2D1Device_Release(bitmap->device); heap_free(bitmap); }
@@ -86,7 +86,7 @@ static void STDMETHODCALLTYPE d2d_bitmap_GetFactory(ID2D1Bitmap1 *iface, ID2D1Fa
TRACE("iface %p, factory %p.\n", iface, factory);
- ID2D1Factory_AddRef(*factory = bitmap->factory); + ID2D1Device_GetFactory(bitmap->device, factory); }
static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_GetSize(ID2D1Bitmap1 *iface, D2D1_SIZE_F *size) @@ -277,7 +277,7 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, struct d2d_device_context
bitmap->ID2D1Bitmap1_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->refcount = 1; - ID2D1Factory_AddRef(bitmap->factory = context->factory); + ID2D1Device_AddRef(bitmap->device = context->device); ID3D10Resource_AddRef(bitmap->resource = resource); bitmap->pixel_size = size; bitmap->format = desc->pixelFormat; @@ -385,14 +385,18 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); + ID2D1Factory *factory; ID3D10Device *device; HRESULT hr = S_OK;
- if (src_impl->factory != context->factory) + ID2D1Device_GetFactory(src_impl->device, &factory); + if (factory != context->factory) { + ID2D1Factory_Release(factory); hr = D2DERR_WRONG_FACTORY; goto failed; } + ID2D1Factory_Release(factory);
ID3D10Resource_GetDevice(src_impl->resource, &device); ID3D10Device_Release(device); diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 4546d5c1e3a..436c4b0f245 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -348,7 +348,7 @@ struct d2d_bitmap ID2D1Bitmap1 ID2D1Bitmap1_iface; LONG refcount;
- ID2D1Factory *factory; + ID2D1Device *device; ID3D10ShaderResourceView *srv; ID3D10RenderTargetView *rtv; IDXGISurface *surface;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d2d1/d2d1_private.h | 1 + dlls/d2d1/device.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 436c4b0f245..7211029d920 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -539,6 +539,7 @@ struct d2d_device LONG refcount; ID2D1Factory1 *factory; IDXGIDevice *dxgi_device; + ID3D10Device *d3d10_device; };
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 5f04c3aa833..3c33fba0e56 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -3875,13 +3875,13 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, render_target->ops = ops;
device_impl = unsafe_impl_from_ID2D1Device(device); - if (FAILED(hr = IDXGIDevice_QueryInterface(device_impl->dxgi_device, - &IID_ID3D10Device, (void **)&render_target->d3d_device))) + if (!device_impl->d3d10_device) { - WARN("Failed to get device interface, hr %#x.\n", hr); + WARN("Failed to get device interface.\n"); ID2D1Factory_Release(render_target->factory); - return hr; + return E_NOINTERFACE; } + ID3D10Device_AddRef(render_target->d3d_device = device_impl->d3d10_device);
if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) { @@ -4126,6 +4126,7 @@ static ULONG WINAPI d2d_device_Release(ID2D1Device *iface)
if (!refcount) { + if (device->d3d10_device) ID3D10Device_Release(device->d3d10_device); IDXGIDevice_Release(device->dxgi_device); ID2D1Factory1_Release(device->factory); heap_free(device); @@ -4223,10 +4224,19 @@ static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface)
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevice *dxgi_device) { + HRESULT hr; + device->ID2D1Device_iface.lpVtbl = &d2d_device_vtbl; device->refcount = 1; device->factory = iface; ID2D1Factory1_AddRef(device->factory); device->dxgi_device = dxgi_device; IDXGIDevice_AddRef(device->dxgi_device); + + if (FAILED(hr = IDXGIDevice_QueryInterface(device->dxgi_device, + &IID_ID3D10Device, (void **)&device->d3d10_device))) + { + WARN("Failed to get device interface, hr %#x.\n", hr); + device->d3d10_device = NULL; + } }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d2d1/d2d1_private.h | 1 + dlls/d2d1/device.c | 8 ++++++++ 2 files changed, 9 insertions(+)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 7211029d920..153113cafa9 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -540,6 +540,7 @@ struct d2d_device ID2D1Factory1 *factory; IDXGIDevice *dxgi_device; ID3D10Device *d3d10_device; + ID3D10Multithread *d3d10_mt; };
void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN; diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 3c33fba0e56..acbcab5caeb 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -4126,6 +4126,7 @@ static ULONG WINAPI d2d_device_Release(ID2D1Device *iface)
if (!refcount) { + if (device->d3d10_mt) ID3D10Multithread_Release(device->d3d10_mt); if (device->d3d10_device) ID3D10Device_Release(device->d3d10_device); IDXGIDevice_Release(device->dxgi_device); ID2D1Factory1_Release(device->factory); @@ -4233,6 +4234,13 @@ void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevic device->dxgi_device = dxgi_device; IDXGIDevice_AddRef(device->dxgi_device);
+ if (FAILED(hr = IDXGIDevice_QueryInterface(device->dxgi_device, + &IID_ID3D10Multithread, (void **)&device->d3d10_mt))) + { + WARN("Failed to get ID3D10Multithread interface, hr %#x.\n", hr); + device->d3d10_mt = NULL; + } + if (FAILED(hr = IDXGIDevice_QueryInterface(device->dxgi_device, &IID_ID3D10Device, (void **)&device->d3d10_device))) {
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d2d1/bitmap.c | 47 +++++++++-- dlls/d2d1/brush.c | 10 ++- dlls/d2d1/d2d1_private.h | 4 +- dlls/d2d1/device.c | 147 ++++++++++++++++++++++++++-------- dlls/d2d1/wic_render_target.c | 24 +++++- 5 files changed, 188 insertions(+), 44 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index bc58d7d92d5..51fefe535fa 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -152,6 +152,7 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap1(iface); ID3D10Device *device; D3D10_BOX box; + HRESULT hr;
TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface, dst_rect, src_data, pitch);
@@ -165,10 +166,15 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, box.back = 1; }
- ID3D10Resource_GetDevice(bitmap->resource, &device); + if (FAILED(hr = d2d_device_get_d3d10_device(bitmap->device, &device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + return hr; + } + ID3D10Device_UpdateSubresource(device, bitmap->resource, 0, dst_rect ? &box : NULL, src_data, pitch, 0); - ID3D10Device_Release(device);
+ d2d_device_release_d3d10_device(bitmap->device, device); return S_OK; }
@@ -316,6 +322,7 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, D2D1_BITMAP_PROPERTIES1 bitmap_desc; D3D10_TEXTURE2D_DESC texture_desc; ID3D10Texture2D *texture; + ID3D10Device *d3d10_device; HRESULT hr;
if (!format_supported(&desc->pixelFormat)) @@ -360,10 +367,17 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, resource_data.pSysMem = src_data; resource_data.SysMemPitch = pitch;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(context->d3d_device, &texture_desc, + if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = ID3D10Device_CreateTexture2D(d3d10_device, &texture_desc, src_data ? &resource_data : NULL, &texture))) { ERR("Failed to create texture, hr %#x.\n", hr); + d2d_device_release_d3d10_device(context->device, d3d10_device); return hr; }
@@ -374,6 +388,7 @@ HRESULT d2d_bitmap_create(struct d2d_device_context *context, D2D1_SIZE_U size, } ID3D10Texture2D_Release(texture);
+ d2d_device_release_d3d10_device(context->device, d3d10_device); return *bitmap ? S_OK : E_OUTOFMEMORY; }
@@ -386,9 +401,15 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, { struct d2d_bitmap *src_impl = unsafe_impl_from_ID2D1Bitmap(data); ID2D1Factory *factory; - ID3D10Device *device; + ID3D10Device *device, *context_device; HRESULT hr = S_OK;
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &context_device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + goto failed; + } + ID2D1Device_GetFactory(src_impl->device, &factory); if (factory != context->factory) { @@ -400,7 +421,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid,
ID3D10Resource_GetDevice(src_impl->resource, &device); ID3D10Device_Release(device); - if (device != context->d3d_device) + if (device != context_device) { hr = D2DERR_UNSUPPORTED_OPERATION; goto failed; @@ -434,6 +455,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, TRACE("Created bitmap %p.\n", *bitmap);
failed: + d2d_device_release_d3d10_device(context->device, context_device); return hr; }
@@ -443,26 +465,35 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, IDXGISurface *surface = data; ID3D10Resource *resource; D2D1_SIZE_U pixel_size; - ID3D10Device *device; + ID3D10Device *device, *context_device; HRESULT hr;
+ if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &context_device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + return hr; + } + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) { WARN("Failed to get d3d resource from dxgi surface.\n"); + d2d_device_release_d3d10_device(context->device, context_device); return E_FAIL; }
ID3D10Resource_GetDevice(resource, &device); ID3D10Device_Release(device); - if (device != context->d3d_device) + if (device != context_device) { ID3D10Resource_Release(resource); + d2d_device_release_d3d10_device(context->device, context_device); return D2DERR_UNSUPPORTED_OPERATION; }
if (!(*bitmap = heap_alloc_zero(sizeof(**bitmap)))) { ID3D10Resource_Release(resource); + d2d_device_release_d3d10_device(context->device, context_device); return E_OUTOFMEMORY; }
@@ -471,6 +502,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, { WARN("Failed to get surface desc, hr %#x.\n", hr); ID3D10Resource_Release(resource); + d2d_device_release_d3d10_device(context->device, context_device); return hr; }
@@ -501,6 +533,7 @@ HRESULT d2d_bitmap_create_shared(struct d2d_device_context *context, REFIID iid, ID3D10Resource_Release(resource); TRACE("Created bitmap %p.\n", *bitmap);
+ d2d_device_release_d3d10_device(context->device, context_device); return S_OK; }
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 07d2e26a143..cc02495a116 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -1267,6 +1267,7 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b D3D10_SUBRESOURCE_DATA buffer_data; struct d2d_ps_cb cb_data = {0}; D3D10_BUFFER_DESC buffer_desc; + ID3D10Device *d3d10_device; HRESULT hr;
cb_data.outline = outline; @@ -1286,9 +1287,16 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, ps_cb))) + if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device))) + { + ERR("Failed to acquire D3D10 device, hr %#x.\n", hr); + return hr; + } + + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, ps_cb))) ERR("Failed to create constant buffer, hr %#x.\n", hr);
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device); return hr; }
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 153113cafa9..cb3421478f0 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -139,7 +139,6 @@ struct d2d_device_context
ID2D1Factory *factory; ID2D1Device *device; - ID3D10Device *d3d_device; struct d2d_bitmap *target; ID3D10StateBlock *stateblock; struct d2d_shape_resources shape_resources[D2D_SHAPE_TYPE_COUNT]; @@ -543,6 +542,9 @@ struct d2d_device ID3D10Multithread *d3d10_mt; };
+HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_device) DECLSPEC_HIDDEN; +void d2d_device_release_d3d10_device(ID2D1Device *iface, ID3D10Device *d3d10_device) DECLSPEC_HIDDEN; + void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDevice *dxgi_device) DECLSPEC_HIDDEN;
struct d2d_effect diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index acbcab5caeb..cfa28e984f9 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -122,7 +122,7 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en ID3D10Buffer *vs_cb, ID3D10Buffer *ps_cb, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { struct d2d_shape_resources *shape_resources = &render_target->shape_resources[shape_type]; - ID3D10Device *device = render_target->d3d_device; + ID3D10Device *device = NULL; D3D10_RECT scissor_rect; unsigned int offset; D3D10_VIEWPORT vp; @@ -135,9 +135,16 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f;
+ if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + return; + } + if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock))) { WARN("Failed to capture stateblock, hr %#x.\n", hr); + d2d_device_release_d3d10_device(render_target->device, device); return; }
@@ -188,6 +195,8 @@ static void d2d_device_context_draw(struct d2d_device_context *render_target, en
if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock))) WARN("Failed to apply stateblock, hr %#x.\n", hr); + + d2d_device_release_d3d10_device(render_target->device, device); }
static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code) @@ -274,7 +283,6 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface) context->stateblock->lpVtbl->Release(context->stateblock); if (context->target) ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface); - ID3D10Device_Release(context->d3d_device); ID2D1Factory_Release(context->factory); ID2D1Device_Release(context->device); heap_free(context); @@ -438,15 +446,23 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateGradientStopCollection { struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface); struct d2d_gradient *object; + ID3D10Device *d3d10_device; HRESULT hr;
TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n", iface, stops, stop_count, gamma, extend_mode, gradient);
- if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, render_target->d3d_device, + if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr); + return hr; + } + + if (SUCCEEDED(hr = d2d_gradient_create(render_target->factory, d3d10_device, stops, stop_count, gamma, extend_mode, &object))) *gradient = &object->ID2D1GradientStopCollection_iface;
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device); return hr; }
@@ -702,6 +718,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; const D2D1_MATRIX_3X2_F *w; + ID3D10Device *d3d10_device; float tmp_x, tmp_y; HRESULT hr; struct @@ -748,9 +765,16 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb))) + if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr); + return; + } + + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb))) { WARN("Failed to create constant buffer, hr %#x.\n", hr); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -758,6 +782,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t { WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -766,6 +791,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); ID3D10Buffer_Release(ps_cb_bezier); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -775,7 +801,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib))) { WARN("Failed to create index buffer, hr %#x.\n", hr); goto done; @@ -785,7 +811,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create vertex buffer, hr %#x.\n", hr); ID3D10Buffer_Release(ib); @@ -805,7 +831,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.bezier_faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib))) { WARN("Failed to create beziers index buffer, hr %#x.\n", hr); goto done; @@ -815,7 +841,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.beziers;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr); ID3D10Buffer_Release(ib); @@ -836,7 +862,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->outline.arc_faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib))) { WARN("Failed to create arcs index buffer, hr %#x.\n", hr); goto done; @@ -846,7 +872,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->outline.arcs;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr); ID3D10Buffer_Release(ib); @@ -865,6 +891,7 @@ done: ID3D10Buffer_Release(ps_cb_arc); ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); }
static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext *iface, @@ -890,6 +917,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; D2D1_MATRIX_3X2_F *w; + ID3D10Device *d3d10_device; float tmp_x, tmp_y; HRESULT hr; struct @@ -936,9 +964,16 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb))) + if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr); + return; + } + + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb))) { WARN("Failed to create constant buffer, hr %#x.\n", hr); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -946,6 +981,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t { WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -954,6 +990,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); ID3D10Buffer_Release(ps_cb_bezier); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -963,7 +1000,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; buffer_data.pSysMem = geometry->fill.faces;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ib))) { WARN("Failed to create index buffer, hr %#x.\n", hr); goto done; @@ -973,7 +1010,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create vertex buffer, hr %#x.\n", hr); ID3D10Buffer_Release(ib); @@ -993,7 +1030,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.bezier_vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr); goto done; @@ -1011,7 +1048,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; buffer_data.pSysMem = geometry->fill.arc_vertices;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vb))) { ERR("Failed to create arc vertex buffer, hr %#x.\n", hr); goto done; @@ -1027,6 +1064,7 @@ done: ID3D10Buffer_Release(ps_cb_arc); ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); }
static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext *iface, @@ -1622,6 +1660,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface D3D10_SUBRESOURCE_DATA buffer_data; struct d2d_ps_cb ps_cb_data = {0}; D3D10_BUFFER_DESC buffer_desc; + ID3D10Device *d3d10_device; ID3D10Buffer *vs_cb, *ps_cb; D2D1_COLOR_F *c; HRESULT hr; @@ -1656,9 +1695,16 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb))) + if (FAILED(hr = d2d_device_get_d3d10_device(render_target->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr); + return; + } + + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &vs_cb))) { WARN("Failed to create constant buffer, hr %#x.\n", hr); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -1679,10 +1725,11 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface buffer_desc.ByteWidth = sizeof(ps_cb_data); buffer_data.pSysMem = &ps_cb_data;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ps_cb))) + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &ps_cb))) { WARN("Failed to create constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); return; }
@@ -1691,6 +1738,7 @@ static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface
ID3D10Buffer_Release(ps_cb); ID3D10Buffer_Release(vs_cb); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); }
static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext *iface) @@ -2028,6 +2076,7 @@ static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *i struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); struct d2d_bitmap *bitmap_impl; D3D10_BLEND_DESC blend_desc; + ID3D10Device *d3d10_device; ID2D1Bitmap *bitmap; HRESULT hr;
@@ -2077,8 +2126,17 @@ static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *i } blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; - if (FAILED(hr = ID3D10Device_CreateBlendState(context->d3d_device, &blend_desc, &context->bs))) + + if (FAILED(hr = d2d_device_get_d3d10_device(context->device, &d3d10_device))) + { + ERR("Failed to get ID3D10Device1 interface, hr %#x.\n", hr); + return; + } + + if (FAILED(hr = ID3D10Device_CreateBlendState(d3d10_device, &blend_desc, &context->bs))) WARN("Failed to create blend state, hr %#x.\n", hr); + + d2d_device_release_d3d10_device(context->device, d3d10_device); }
static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext *iface, ID2D1Image **target) @@ -2803,17 +2861,42 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe d2d_gdi_interop_render_target_ReleaseDC, };
+HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_device) +{ + struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface); + + if (!device->d3d10_device) + { + WARN("Failed to get device interface.\n"); + return E_NOINTERFACE; + } + + if (device->d3d10_mt) ID3D10Multithread_Enter(device->d3d10_mt); + + ID3D10Device_AddRef(*d3d10_device = device->d3d10_device); + return S_OK; +} + +void d2d_device_release_d3d10_device(ID2D1Device *iface, ID3D10Device *d3d10_device) +{ + struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface); + + ID3D10Device_Release(d3d10_device); + + if (device->d3d10_mt) ID3D10Multithread_Leave(device->d3d10_mt); +} + static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device, IUnknown *outer_unknown, const struct d2d_device_context_ops *ops) { D3D10_SUBRESOURCE_DATA buffer_data; D3D10_STATE_BLOCK_MASK state_mask; - struct d2d_device *device_impl; IDWriteFactory *dwrite_factory; D3D10_RASTERIZER_DESC rs_desc; D3D10_BUFFER_DESC buffer_desc; unsigned int i; HRESULT hr; + ID3D10Device *d3d10_device = NULL;
static const D3D10_INPUT_ELEMENT_DESC il_desc_outline[] = { @@ -3874,14 +3957,12 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface; render_target->ops = ops;
- device_impl = unsafe_impl_from_ID2D1Device(device); - if (!device_impl->d3d10_device) + if (FAILED(hr = d2d_device_get_d3d10_device(device, &d3d10_device))) { - WARN("Failed to get device interface.\n"); + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); ID2D1Factory_Release(render_target->factory); - return E_NOINTERFACE; + return hr; } - ID3D10Device_AddRef(render_target->d3d_device = device_impl->d3d10_device);
if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) { @@ -3889,7 +3970,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, goto err; }
- if (FAILED(hr = D3D10CreateStateBlock(render_target->d3d_device, &state_mask, &render_target->stateblock))) + if (FAILED(hr = D3D10CreateStateBlock(d3d10_device, &state_mask, &render_target->stateblock))) { WARN("Failed to create stateblock, hr %#x.\n", hr); goto err; @@ -3899,14 +3980,14 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { const struct shape_info *si = &shape_info[i];
- if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->d3d_device, si->il_desc, si->il_element_count, + if (FAILED(hr = ID3D10Device_CreateInputLayout(d3d10_device, si->il_desc, si->il_element_count, si->vs_code, si->vs_code_size, &render_target->shape_resources[si->shape_type].il))) { WARN("Failed to create input layout for shape type %#x, hr %#x.\n", si->shape_type, hr); goto err; }
- if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->d3d_device, si->vs_code, + if (FAILED(hr = ID3D10Device_CreateVertexShader(d3d10_device, si->vs_code, si->vs_code_size, &render_target->shape_resources[si->shape_type].vs))) { WARN("Failed to create vertex shader for shape type %#x, hr %#x.\n", si->shape_type, hr); @@ -3915,7 +3996,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target,
}
- if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->d3d_device, + if (FAILED(hr = ID3D10Device_CreatePixelShader(d3d10_device, ps_code, sizeof(ps_code), &render_target->ps))) { WARN("Failed to create pixel shader, hr %#x.\n", hr); @@ -3932,7 +4013,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, buffer_data.SysMemPitch = 0; buffer_data.SysMemSlicePitch = 0;
- if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &render_target->ib))) { WARN("Failed to create clear index buffer, hr %#x.\n", hr); @@ -3944,7 +4025,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, buffer_data.pSysMem = quad;
render_target->vb_stride = sizeof(*quad); - if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, + if (FAILED(hr = ID3D10Device_CreateBuffer(d3d10_device, &buffer_desc, &buffer_data, &render_target->vb))) { WARN("Failed to create clear vertex buffer, hr %#x.\n", hr); @@ -3961,7 +4042,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, rs_desc.ScissorEnable = TRUE; rs_desc.MultisampleEnable = FALSE; rs_desc.AntialiasedLineEnable = FALSE; - if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->d3d_device, &rs_desc, &render_target->rs))) + if (FAILED(hr = ID3D10Device_CreateRasterizerState(d3d10_device, &rs_desc, &render_target->rs))) { WARN("Failed to create clear rasterizer state, hr %#x.\n", hr); goto err; @@ -3994,6 +4075,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, render_target->desc.dpiX = 96.0f; render_target->desc.dpiY = 96.0f;
+ d2d_device_release_d3d10_device(render_target->device, d3d10_device); return S_OK;
err: @@ -4016,8 +4098,7 @@ err: } if (render_target->stateblock) render_target->stateblock->lpVtbl->Release(render_target->stateblock); - if (render_target->d3d_device) - ID3D10Device_Release(render_target->d3d_device); + d2d_device_release_d3d10_device(render_target->device, d3d10_device); ID2D1Device_Release(render_target->device); ID2D1Factory_Release(render_target->factory); return hr; diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c index 9b57a5d2c34..2d8d7edcd9b 100644 --- a/dlls/d2d1/wic_render_target.c +++ b/dlls/d2d1/wic_render_target.c @@ -31,15 +31,34 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown) { struct d2d_wic_render_target *render_target = impl_from_IUnknown(outer_unknown); D3D10_MAPPED_TEXTURE2D mapped_texture; + ID2D1DeviceContext *d2d1_context; ID3D10Resource *src_resource; IWICBitmapLock *bitmap_lock; UINT dst_size, dst_pitch; ID3D10Device *device; + ID2D1Device *d2d1_device; WICRect dst_rect; BYTE *src, *dst; unsigned int i; HRESULT hr;
+ if (FAILED(hr = ID2D1RenderTarget_QueryInterface(render_target->dxgi_target, + &IID_ID2D1DeviceContext, (void **)&d2d1_context))) + { + WARN("Failed to retrieve ID2D1DeviceContext interface, hr %#x.\n", hr); + return hr; + } + + ID2D1DeviceContext_GetDevice(d2d1_context, &d2d1_device); + + if (FAILED(hr = d2d_device_get_d3d10_device(d2d1_device, &device))) + { + ERR("Failed to get ID3D10Device interface, hr %#x.\n", hr); + ID2D1DeviceContext_Release(d2d1_context); + ID2D1Device_Release(d2d1_device); + return hr; + } + if (FAILED(hr = IDXGISurface_QueryInterface(render_target->dxgi_surface, &IID_ID3D10Resource, (void **)&src_resource))) { @@ -47,9 +66,7 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown) goto end; }
- ID3D10Texture2D_GetDevice(render_target->readback_texture, &device); ID3D10Device_CopyResource(device, (ID3D10Resource *)render_target->readback_texture, src_resource); - ID3D10Device_Release(device); ID3D10Resource_Release(src_resource);
dst_rect.X = 0; @@ -96,6 +113,9 @@ static HRESULT d2d_wic_render_target_present(IUnknown *outer_unknown) IWICBitmapLock_Release(bitmap_lock);
end: + d2d_device_release_d3d10_device(d2d1_device, device); + ID2D1DeviceContext_Release(d2d1_context); + ID2D1Device_Release(d2d1_device); return S_OK; }
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49395 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/d2d1/d2d1_private.h | 6 ++++- dlls/d2d1/device.c | 54 ++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index cb3421478f0..e2794c8b1a2 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -27,7 +27,7 @@ #include <math.h> #define COBJMACROS #include "d2d1_2.h" -#include "d3d11.h" +#include "d3d11_1.h" #ifdef D2D1_INIT_GUID #include "initguid.h" #endif @@ -539,6 +539,10 @@ struct d2d_device ID2D1Factory1 *factory; IDXGIDevice *dxgi_device; ID3D10Device *d3d10_device; + ID3D11Device1 *d3d11_device; + ID3DDeviceContextState *d3d_dc_state; + ID3DDeviceContextState *prev_d3d_dc_state; + LONG d3d_dc_state_recursion; ID3D10Multithread *d3d10_mt; };
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index cfa28e984f9..11722a19eed 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -2864,6 +2864,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_device) { struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface); + ID3D11DeviceContext1 *d3d11_context;
if (!device->d3d10_device) { @@ -2873,6 +2874,16 @@ HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_dev
if (device->d3d10_mt) ID3D10Multithread_Enter(device->d3d10_mt);
+ if (device->d3d11_device && !device->d3d_dc_state_recursion) + { + ID3D11Device1_GetImmediateContext1(device->d3d11_device, &d3d11_context); + ID3D11DeviceContext1_SwapDeviceContextState(d3d11_context, device->d3d_dc_state, &device->prev_d3d_dc_state); + ID3D11DeviceContext1_Release(d3d11_context); + device->d3d_dc_state_recursion = 1; + } + else if (device->d3d_dc_state_recursion) + device->d3d_dc_state_recursion++; + ID3D10Device_AddRef(*d3d10_device = device->d3d10_device); return S_OK; } @@ -2880,6 +2891,16 @@ HRESULT d2d_device_get_d3d10_device(ID2D1Device *iface, ID3D10Device **d3d10_dev void d2d_device_release_d3d10_device(ID2D1Device *iface, ID3D10Device *d3d10_device) { struct d2d_device *device = unsafe_impl_from_ID2D1Device(iface); + ID3D11DeviceContext1 *d3d11_context; + + if (device->d3d11_device && !--device->d3d_dc_state_recursion) + { + ID3D11Device1_GetImmediateContext1(device->d3d11_device, &d3d11_context); + ID3D11DeviceContext1_SwapDeviceContextState(d3d11_context, device->prev_d3d_dc_state, NULL); + ID3DDeviceContextState_Release(device->prev_d3d_dc_state); + ID3D11DeviceContext1_Release(d3d11_context); + device->prev_d3d_dc_state = NULL; + }
ID3D10Device_Release(d3d10_device);
@@ -4208,6 +4229,8 @@ static ULONG WINAPI d2d_device_Release(ID2D1Device *iface) if (!refcount) { if (device->d3d10_mt) ID3D10Multithread_Release(device->d3d10_mt); + if (device->d3d_dc_state) ID3DDeviceContextState_Release(device->d3d_dc_state); + if (device->d3d11_device) ID3D11Device1_Release(device->d3d11_device); if (device->d3d10_device) ID3D10Device_Release(device->d3d10_device); IDXGIDevice_Release(device->dxgi_device); ID2D1Factory1_Release(device->factory); @@ -4324,8 +4347,39 @@ void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevic
if (FAILED(hr = IDXGIDevice_QueryInterface(device->dxgi_device, &IID_ID3D10Device, (void **)&device->d3d10_device))) + { + ID3D11DeviceContext1 *d3d11_context; + DWORD levels = D3D_FEATURE_LEVEL_10_1; + + if (FAILED(hr = IDXGIDevice_QueryInterface(device->dxgi_device, + &IID_ID3D11Device1, (void **)&device->d3d11_device))) + goto done; + + if (FAILED(hr = ID3D11Device1_CreateDeviceContextState(device->d3d11_device, 0, + &levels, 1, D3D11_SDK_VERSION, &IID_ID3D10Device, NULL, &device->d3d_dc_state))) + goto done; + + ID3D11Device1_GetImmediateContext1(device->d3d11_device, &d3d11_context); + + if (device->d3d10_mt) ID3D10Multithread_Enter(device->d3d10_mt); + ID3D11DeviceContext1_SwapDeviceContextState(d3d11_context, device->d3d_dc_state, &device->prev_d3d_dc_state); + hr = ID3D11Device1_QueryInterface(device->d3d11_device, &IID_ID3D10Device, (void **)&device->d3d10_device); + ID3D11DeviceContext1_SwapDeviceContextState(d3d11_context, device->prev_d3d_dc_state, NULL); + if (device->d3d10_mt) ID3D10Multithread_Leave(device->d3d10_mt); + + ID3DDeviceContextState_Release(device->prev_d3d_dc_state); + ID3D11DeviceContext1_Release(d3d11_context); + device->prev_d3d_dc_state = NULL; + } + +done: + if (FAILED(hr)) { WARN("Failed to get device interface, hr %#x.\n", hr); device->d3d10_device = NULL; + if (device->d3d_dc_state) ID3DDeviceContextState_Release(device->d3d_dc_state); + device->d3d_dc_state = NULL; + if (device->d3d11_device) ID3D11Device1_Release(device->d3d11_device); + device->d3d11_device = NULL; } } diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 3e7df715dda..a1166b1ebb8 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -921,7 +921,7 @@ static ID2D1RenderTarget *create_render_target_desc(IDXGISurface *surface, hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, desc, &render_target); - todo_wine_if(d3d11) ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr); ID2D1Factory_Release(factory);
if (FAILED(hr))
On Mon, 18 Jan 2021 at 13:59, Rémi Bernon rbernon@codeweavers.com wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49395 Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/d2d1/d2d1_private.h | 6 ++++- dlls/d2d1/device.c | 54 ++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-)
Is the design of this series purely a consequence of the decision to not implement state swapping in d3d11_immediate_context_SwapDeviceContextState(), or is there some other consideration I'm overlooking? In particular, without having done an attempt at implementing this myself, the "natural" implementation to me would seem to simply replace existing usage of d3d10 interfaces with their d3d11 equivalents, where the ID3DDeviceContextState interface would be the equivalent of the ID3D10StateBlock interface.
On 1/19/21 6:13 PM, Henri Verbeet wrote:
On Mon, 18 Jan 2021 at 13:59, Rémi Bernon rbernon@codeweavers.com wrote:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49395 Signed-off-by: Rémi Bernon rbernon@codeweavers.com
dlls/d2d1/d2d1_private.h | 6 ++++- dlls/d2d1/device.c | 54 ++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-)
Is the design of this series purely a consequence of the decision to not implement state swapping in d3d11_immediate_context_SwapDeviceContextState(), or is there some other consideration I'm overlooking? In particular, without having done an attempt at implementing this myself, the "natural" implementation to me would seem to simply replace existing usage of d3d10 interfaces with their d3d11 equivalents, where the ID3DDeviceContextState interface would be the equivalent of the ID3D10StateBlock interface.
Well, I imagined D2D1 should still have to work over D3D10-only devices? Although I'm not sure if there's such a thing it didn't seem obvious to me that every D3D10 device is also a D3D11 device.
On Tue, 19 Jan 2021 at 18:44, Rémi Bernon rbernon@codeweavers.com wrote:
Well, I imagined D2D1 should still have to work over D3D10-only devices? Although I'm not sure if there's such a thing it didn't seem obvious to me that every D3D10 device is also a D3D11 device.
They certainly are on Wine. There are some early Vista versions where that's not the case, but I wouldn't necessarily expect a d2d1.dll from Windows 10 or 7 to work well on such a configuration either.
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=84139
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5804: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5805: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5806: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5809: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5810: Test failed: Got unexpected CPrimitives count: 0.
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5804: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5805: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5806: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5809: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5810: Test failed: Got unexpected CPrimitives count: 0.
On Mon, 18 Jan 2021 at 13:58, Rémi Bernon rbernon@codeweavers.com wrote:
The idea here is only to have a minimal implementation of SwapDeviceContextState, to fix the D2D1 over D3D11 regression. What's missing is the actual state change, as well as the enabling / disabling or the D3D10 / D3D11 interface methods when state is changed to another version, as described in [1].
I didn't really investigate what the full device context state implementation would require, but I suspect it to be much bigger scope. This could possibly serve as an initial work for it as well.
That makes it a fair bit harder to judge whether this is really the right way to go, of course. My expectation would be that implementing state save/restore would only be marginally more complicated than the current d3d10 stateblock implementation.