From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d11/Makefile.in | 1 + dlls/d3d11/d3d11_private.h | 12 +++ dlls/d3d11/decoder.c | 160 +++++++++++++++++++++++++++++++++++++ dlls/d3d11/device.c | 11 ++- 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 dlls/d3d11/decoder.c
diff --git a/dlls/d3d11/Makefile.in b/dlls/d3d11/Makefile.in index 83f49602a46..27db1f637f2 100644 --- a/dlls/d3d11/Makefile.in +++ b/dlls/d3d11/Makefile.in @@ -7,6 +7,7 @@ SOURCES = \ async.c \ buffer.c \ d3d11_main.c \ + decoder.c \ device.c \ inputlayout.c \ shader.c \ diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index ef9ba5e8afb..57ed210a282 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -601,6 +601,18 @@ static inline struct d3d_device *impl_from_ID3D10Device(ID3D10Device1 *iface)
void d3d_device_init(struct d3d_device *device, void *outer_unknown);
+struct d3d_video_decoder +{ + ID3D11VideoDecoder ID3D11VideoDecoder_iface; + LONG refcount; + + struct wined3d_private_store private_store; + struct d3d_device *device; +}; + +HRESULT d3d_video_decoder_create(struct d3d_device *device, const D3D11_VIDEO_DECODER_DESC *desc, + const D3D11_VIDEO_DECODER_CONFIG *config, struct d3d_video_decoder **decoder); + /* Layered device */ enum dxgi_device_layer_id { diff --git a/dlls/d3d11/decoder.c b/dlls/d3d11/decoder.c new file mode 100644 index 00000000000..5caf7b66c93 --- /dev/null +++ b/dlls/d3d11/decoder.c @@ -0,0 +1,160 @@ +/* + * Copyright 2024 Elizabeth Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "d3d11_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d11); + +static struct d3d_video_decoder *impl_from_ID3D11VideoDecoder(ID3D11VideoDecoder *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_video_decoder, ID3D11VideoDecoder_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_QueryInterface(ID3D11VideoDecoder *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D11VideoDecoder) + || IsEqualGUID(riid, &IID_ID3D11DeviceChild) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D11VideoDecoder_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d11_video_decoder_AddRef(ID3D11VideoDecoder *iface) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + ULONG refcount = InterlockedIncrement(&decoder->refcount); + + TRACE("%p increasing refcount to %lu.\n", decoder, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d11_video_decoder_Release(ID3D11VideoDecoder *iface) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + ULONG refcount = InterlockedDecrement(&decoder->refcount); + + TRACE("%p decreasing refcount to %lu.\n", decoder, refcount); + + if (!refcount) + { + ID3D11Device2_Release(&decoder->device->ID3D11Device2_iface); + wined3d_private_store_cleanup(&decoder->private_store); + free(decoder); + } + + return refcount; +} + +static void STDMETHODCALLTYPE d3d11_video_decoder_GetDevice(ID3D11VideoDecoder *iface, ID3D11Device **device) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = (ID3D11Device *)decoder->device; + ID3D11Device_AddRef(*device); +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_GetPrivateData(ID3D11VideoDecoder *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_get_private_data(&decoder->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_SetPrivateData(ID3D11VideoDecoder *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return d3d_set_private_data(&decoder->private_store, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_SetPrivateDataInterface(ID3D11VideoDecoder *iface, + REFGUID guid, const IUnknown *data) +{ + struct d3d_video_decoder *decoder = impl_from_ID3D11VideoDecoder(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return d3d_set_private_data_interface(&decoder->private_store, guid, data); +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_GetCreationParameters(ID3D11VideoDecoder *iface, + D3D11_VIDEO_DECODER_DESC *desc, D3D11_VIDEO_DECODER_CONFIG *config) +{ + FIXME("iface %p, desc %p, config %p, stub!\n", iface, desc, config); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d11_video_decoder_GetDriverHandle(ID3D11VideoDecoder *iface, HANDLE *handle) +{ + FIXME("iface %p, handle %p, stub!\n", iface, handle); + return E_NOTIMPL; +} + +static const struct ID3D11VideoDecoderVtbl d3d11_video_decoder_vtbl = +{ + d3d11_video_decoder_QueryInterface, + d3d11_video_decoder_AddRef, + d3d11_video_decoder_Release, + d3d11_video_decoder_GetDevice, + d3d11_video_decoder_GetPrivateData, + d3d11_video_decoder_SetPrivateData, + d3d11_video_decoder_SetPrivateDataInterface, + d3d11_video_decoder_GetCreationParameters, + d3d11_video_decoder_GetDriverHandle, +}; + +HRESULT d3d_video_decoder_create(struct d3d_device *device, const D3D11_VIDEO_DECODER_DESC *desc, + const D3D11_VIDEO_DECODER_CONFIG *config, struct d3d_video_decoder **decoder) +{ + struct d3d_video_decoder *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID3D11VideoDecoder_iface.lpVtbl = &d3d11_video_decoder_vtbl; + object->refcount = 1; + + wined3d_private_store_init(&object->private_store); + object->device = device; + ID3D11Device2_AddRef(&device->ID3D11Device2_iface); + + TRACE("Created video decoder %p.\n", object); + *decoder = object; + return S_OK; +} diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index bdd80e90416..540fbfc7894 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -6807,8 +6807,17 @@ static ULONG STDMETHODCALLTYPE d3d11_video_device_Release(ID3D11VideoDevice1 *if static HRESULT STDMETHODCALLTYPE d3d11_video_device_CreateVideoDecoder(ID3D11VideoDevice1 *iface, const D3D11_VIDEO_DECODER_DESC *desc, const D3D11_VIDEO_DECODER_CONFIG *config, ID3D11VideoDecoder **decoder) { + struct d3d_device *device = impl_from_ID3D11VideoDevice1(iface); + struct d3d_video_decoder *object; + HRESULT hr; + FIXME("iface %p, desc %p, config %p, decoder %p, stub!\n", iface, desc, config, decoder); - return E_NOTIMPL; + + if (FAILED(hr = d3d_video_decoder_create(device, desc, config, &object))) + return hr; + + *decoder = &object->ID3D11VideoDecoder_iface; + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d11_video_device_CreateVideoProcessor(ID3D11VideoDevice1 *iface,