From: Elizabeth Figura zfigura@codeweavers.com
This patch is just boilerplate. --- dlls/d3d11/d3d11_private.h | 1 + dlls/d3d11/decoder.c | 53 +++++++++++++++++ dlls/wined3d/decoder.c | 105 +++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 3 + dlls/wined3d/wined3d_private.h | 3 + include/wine/wined3d.h | 13 ++++ 6 files changed, 178 insertions(+)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 68745e3b815..910ad226269 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -623,6 +623,7 @@ struct d3d_video_decoder
struct wined3d_private_store private_store; struct d3d_device *device; + struct wined3d_decoder *wined3d_decoder; };
HRESULT d3d_video_decoder_create(struct d3d_device *device, const D3D11_VIDEO_DECODER_DESC *desc, diff --git a/dlls/d3d11/decoder.c b/dlls/d3d11/decoder.c index 5caf7b66c93..1e61dea0581 100644 --- a/dlls/d3d11/decoder.c +++ b/dlls/d3d11/decoder.c @@ -18,6 +18,8 @@ */
#include "d3d11_private.h" +#include "initguid.h" +#include "dxva.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
@@ -65,6 +67,7 @@ static ULONG STDMETHODCALLTYPE d3d11_video_decoder_Release(ID3D11VideoDecoder *i
if (!refcount) { + wined3d_decoder_decref(decoder->wined3d_decoder); ID3D11Device2_Release(&decoder->device->ID3D11Device2_iface); wined3d_private_store_cleanup(&decoder->private_store); free(decoder); @@ -142,7 +145,32 @@ static const struct ID3D11VideoDecoderVtbl d3d11_video_decoder_vtbl = 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 wined3d_decoder_desc wined3d_desc; struct d3d_video_decoder *object; + HRESULT hr; + + TRACE("profile %s, size %ux%u, output format %#x.\n", + debugstr_guid(&desc->Guid), desc->SampleWidth, desc->SampleHeight, desc->OutputFormat); + + TRACE(" guidConfigBitstreamEncryption: %s\n", debugstr_guid(&config->guidConfigBitstreamEncryption)); + TRACE(" guidConfigMBcontrolEncryption: %s\n", debugstr_guid(&config->guidConfigMBcontrolEncryption)); + TRACE(" guidConfigResidDiffEncryption: %s\n", debugstr_guid(&config->guidConfigResidDiffEncryption)); +#define X(field) TRACE(" " #field ": %u\n", config->field) + X(ConfigBitstreamRaw); + X(ConfigMBcontrolRasterOrder); + X(ConfigResidDiffHost); + X(ConfigSpatialResid8); + X(ConfigResid8Subtraction); + X(ConfigSpatialHost8or9Clipping); + X(ConfigSpatialResidInterleaved); + X(ConfigIntraResidUnsigned); + X(ConfigResidDiffAccelerator); + X(ConfigHostInverseScan); + X(ConfigSpecificIDCT); + X(Config4GroupedCoefs); + X(ConfigMinRenderTargetBuffCount); + X(ConfigDecoderSpecific); +#undef X
if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; @@ -150,6 +178,31 @@ HRESULT d3d_video_decoder_create(struct d3d_device *device, const D3D11_VIDEO_DE object->ID3D11VideoDecoder_iface.lpVtbl = &d3d11_video_decoder_vtbl; object->refcount = 1;
+ wined3d_desc.codec = desc->Guid; + wined3d_desc.width = desc->SampleWidth; + wined3d_desc.height = desc->SampleHeight; + wined3d_desc.output_format = wined3dformat_from_dxgi_format(desc->OutputFormat); + wined3d_desc.long_slice_info = false; + + if (IsEqualGUID(&wined3d_desc.codec, &DXVA_ModeH264_VLD_NoFGT)) + { + if (config->ConfigBitstreamRaw == 1) + { + wined3d_desc.long_slice_info = true; + } + else if (config->ConfigBitstreamRaw != 2) + { + FIXME("Unsupported ConfigBitstreamRaw value %u.\n", config->ConfigBitstreamRaw); + return E_NOTIMPL; + } + } + + if (FAILED(hr = wined3d_decoder_create(device->wined3d_device, &wined3d_desc, &object->wined3d_decoder))) + { + free(object); + return hr; + } + wined3d_private_store_init(&object->private_store); object->device = device; ID3D11Device2_AddRef(&device->ID3D11Device2_iface); diff --git a/dlls/wined3d/decoder.c b/dlls/wined3d/decoder.c index 2da2f5c3c79..0752849eca2 100644 --- a/dlls/wined3d/decoder.c +++ b/dlls/wined3d/decoder.c @@ -21,6 +21,67 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+struct wined3d_decoder +{ + LONG ref; + struct wined3d_device *device; + struct wined3d_decoder_desc desc; +}; + +ULONG CDECL wined3d_decoder_decref(struct wined3d_decoder *decoder) +{ + unsigned int refcount = InterlockedDecrement(&decoder->ref); + + TRACE("%p decreasing refcount to %u.\n", decoder, refcount); + + if (!refcount) + { + wined3d_mutex_lock(); + decoder->device->adapter->decoder_ops->destroy(decoder); + wined3d_mutex_unlock(); + } + + return refcount; +} + +static bool is_supported_codec(struct wined3d_adapter *adapter, const GUID *codec) +{ + GUID profiles[WINED3D_DECODER_MAX_PROFILE_COUNT]; + unsigned int count; + + adapter->decoder_ops->get_profiles(adapter, &count, profiles); + + for (unsigned int i = 0; i < count; ++i) + { + if (IsEqualGUID(&profiles[i], codec)) + return true; + } + return false; +} + +static void wined3d_decoder_init(struct wined3d_decoder *decoder, + struct wined3d_device *device, const struct wined3d_decoder_desc *desc) +{ + decoder->ref = 1; + decoder->device = device; + decoder->desc = *desc; +} + +HRESULT CDECL wined3d_decoder_create(struct wined3d_device *device, + const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder) +{ + TRACE("device %p, codec %s, size %ux%u, output_format %s, decoder %p.\n", device, + debugstr_guid(&desc->codec), desc->width, desc->height, debug_d3dformat(desc->output_format), decoder); + + if (!is_supported_codec(device->adapter, &desc->codec)) + { + WARN("Codec %s is not supported; returning E_INVALIDARG.\n", debugstr_guid(&desc->codec)); + return E_INVALIDARG; + } + + return device->adapter->decoder_ops->create(device, desc, decoder); +} + static void wined3d_null_decoder_get_profiles(struct wined3d_adapter *adapter, unsigned int *count, GUID *profiles) { *count = 0; @@ -31,6 +92,16 @@ const struct wined3d_decoder_ops wined3d_null_decoder_ops = .get_profiles = wined3d_null_decoder_get_profiles, };
+struct wined3d_decoder_vk +{ + struct wined3d_decoder d; +}; + +static struct wined3d_decoder_vk *wined3d_decoder_vk(struct wined3d_decoder *decoder) +{ + return CONTAINING_RECORD(decoder, struct wined3d_decoder_vk, d); +} + static void fill_vk_profile_info(VkVideoProfileInfoKHR *profile, const GUID *codec, enum wined3d_format_id format) { profile->sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR; @@ -122,7 +193,41 @@ static void wined3d_decoder_vk_get_profiles(struct wined3d_adapter *adapter, uns } }
+static void wined3d_decoder_vk_destroy_object(void *object) +{ + struct wined3d_video_decoder_vk *decoder_vk = object; + + TRACE("decoder_vk %p.\n", decoder_vk); + + free(decoder_vk); +} + +static void wined3d_decoder_vk_destroy(struct wined3d_decoder *decoder) +{ + struct wined3d_decoder_vk *decoder_vk = wined3d_decoder_vk(decoder); + + wined3d_cs_destroy_object(decoder->device->cs, wined3d_decoder_vk_destroy_object, decoder_vk); +} + +static HRESULT wined3d_decoder_vk_create(struct wined3d_device *device, + const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder) +{ + struct wined3d_decoder_vk *object; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + wined3d_decoder_init(&object->d, device, desc); + + TRACE("Created decoder %p.\n", object); + *decoder = &object->d; + + return WINED3D_OK; +} + const struct wined3d_decoder_ops wined3d_decoder_vk_ops = { .get_profiles = wined3d_decoder_vk_get_profiles, + .create = wined3d_decoder_vk_create, + .destroy = wined3d_decoder_vk_destroy, }; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e0b15c02b42..6fdc2002ca3 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -40,6 +40,9 @@ @ cdecl wined3d_command_list_decref(ptr) @ cdecl wined3d_command_list_incref(ptr)
+@ cdecl wined3d_decoder_create(ptr ptr ptr) +@ cdecl wined3d_decoder_decref(ptr) + @ cdecl wined3d_deferred_context_create(ptr ptr) @ cdecl wined3d_deferred_context_destroy(ptr) @ cdecl wined3d_deferred_context_record_command_list(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7b0f6469538..bf8f3f12d59 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4466,6 +4466,9 @@ struct wined3d_palette struct wined3d_decoder_ops { void (*get_profiles)(struct wined3d_adapter *adapter, unsigned int *count, GUID *profiles); + HRESULT (*create)(struct wined3d_device *device, + const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder); + void (*destroy)(struct wined3d_decoder *decoder); };
extern const struct wined3d_decoder_ops wined3d_decoder_vk_ops; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 1b2b37fdfd0..27e211a0b4e 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2050,6 +2050,14 @@ struct wined3d_blend_state_desc } rt[WINED3D_MAX_RENDER_TARGETS]; };
+struct wined3d_decoder_desc +{ + GUID codec; + unsigned int width, height; + enum wined3d_format_id output_format; + bool long_slice_info; +}; + struct wined3d_stencil_op_desc { enum wined3d_stencil_op fail_op; @@ -2223,6 +2231,7 @@ struct wined3d_adapter; struct wined3d_blend_state; struct wined3d_buffer; struct wined3d_command_list; +struct wined3d_decoder; struct wined3d_depth_stencil_state; struct wined3d_device; struct wined3d_device_context; @@ -2357,6 +2366,10 @@ 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_decoder_create(struct wined3d_device *device, + const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder); +ULONG __cdecl wined3d_decoder_decref(struct wined3d_decoder *decoder); + 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,