From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/wined3d/adapter_vk.c | 8 +++- dlls/wined3d/decoder.c | 67 ++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_main.c | 14 +++++++ dlls/wined3d/wined3d_private.h | 9 +++++ 4 files changed, 97 insertions(+), 1 deletion(-) diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 7f68edb3651..a88faf2c9ce 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -2608,7 +2608,13 @@ static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk, adapter->fragment_pipe = wined3d_spirv_fragment_pipe_init_vk(); adapter->misc_state_template = misc_state_template_vk; adapter->shader_backend = wined3d_spirv_shader_backend_init_vk(); - adapter->decoder_ops = &wined3d_decoder_vk_ops; + + if (wined3d_settings.decoder_backend == WINED3D_DECODER_BACKEND_VA + || (wined3d_settings.decoder_backend == WINED3D_DECODER_BACKEND_AUTO + && !vk_info->supported[WINED3D_VK_KHR_VIDEO_DECODE_H264])) + adapter->decoder_ops = &wined3d_decoder_va_vk_ops; + else + adapter->decoder_ops = &wined3d_decoder_vk_ops; wined3d_adapter_vk_init_d3d_info(adapter_vk, wined3d_creation_flags); diff --git a/dlls/wined3d/decoder.c b/dlls/wined3d/decoder.c index ef37fe05f0f..18f987b6ed6 100644 --- a/dlls/wined3d/decoder.c +++ b/dlls/wined3d/decoder.c @@ -1354,6 +1354,73 @@ const struct wined3d_decoder_ops wined3d_decoder_vk_ops = .decode = wined3d_decoder_vk_decode, }; +struct wined3d_decoder_va_vk +{ + struct wined3d_decoder d; +}; + +static struct wined3d_decoder_va_vk *wined3d_decoder_va_vk(struct wined3d_decoder *decoder) +{ + return CONTAINING_RECORD(decoder, struct wined3d_decoder_va_vk, d); +} + +static void wined3d_decoder_va_vk_get_profiles(struct wined3d_adapter *adapter, unsigned int *count, GUID *profiles) +{ + *count = 0; +} + +static HRESULT wined3d_decoder_va_vk_create(struct wined3d_device *device, + const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder) +{ + struct wined3d_decoder_va_vk *object; + HRESULT hr; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + if (FAILED(hr = wined3d_decoder_init(&object->d, device, desc))) + { + free(object); + return hr; + } + + TRACE("Created decoder %p.\n", object); + *decoder = &object->d; + + return WINED3D_OK; +} + +static void wined3d_decoder_va_vk_destroy_object(void *object) +{ + struct wined3d_decoder_va_vk *decoder_va = object; + + TRACE("decoder_va %p.\n", decoder_va); + + free(decoder_va); +} + +static void wined3d_decoder_va_vk_destroy(struct wined3d_decoder *decoder) +{ + struct wined3d_decoder_va_vk *decoder_va = wined3d_decoder_va_vk(decoder); + + wined3d_decoder_cleanup(&decoder_va->d); + wined3d_cs_destroy_object(decoder->device->cs, wined3d_decoder_va_vk_destroy_object, decoder_va); +} + +static void wined3d_decoder_va_vk_decode(struct wined3d_context *context, + struct wined3d_decoder *decoder, struct wined3d_decoder_output_view *output_view, + unsigned int bitstream_size, unsigned int slice_control_size) +{ + FIXME("Not implemented.\n"); +} + +const struct wined3d_decoder_ops wined3d_decoder_va_vk_ops = +{ + .get_profiles = wined3d_decoder_va_vk_get_profiles, + .create = wined3d_decoder_va_vk_create, + .destroy = wined3d_decoder_va_vk_destroy, + .decode = wined3d_decoder_va_vk_decode, +}; + struct wined3d_resource * CDECL wined3d_decoder_get_buffer( struct wined3d_decoder *decoder, enum wined3d_decoder_buffer_type type) { diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 91d8dd567ff..976ea72d69c 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -129,6 +129,7 @@ struct wined3d_settings wined3d_settings = .max_sm_cs = UINT_MAX, .renderer = WINED3D_RENDERER_AUTO, .shader_backend = WINED3D_SHADER_BACKEND_AUTO, + .decoder_backend = WINED3D_DECODER_BACKEND_AUTO, }; enum wined3d_renderer CDECL wined3d_get_renderer(void) @@ -363,6 +364,19 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) wined3d_settings.shader_backend = WINED3D_SHADER_BACKEND_GLSL; } } + if (!get_config_key(hkey, appkey, env, "decoder_backend", buffer, size)) + { + if (!stricmp(buffer, "vulkan")) + { + ERR_(winediag)("Using the Vulkan video decoder backend.\n"); + wined3d_settings.decoder_backend = WINED3D_DECODER_BACKEND_VULKAN; + } + else if (!stricmp(buffer, "va")) + { + ERR_(winediag)("Using the VA video decoder backend.\n"); + wined3d_settings.decoder_backend = WINED3D_DECODER_BACKEND_VA; + } + } if (!get_config_key_dword(hkey, appkey, env, "VideoPciDeviceID", &tmpvalue)) { int pci_device_id = tmpvalue; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 9537670f7c5..1be740c94b3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -457,6 +457,13 @@ enum wined3d_shader_backend WINED3D_SHADER_BACKEND_GLSL_VKD3D, }; +enum wined3d_decoder_backend +{ + WINED3D_DECODER_BACKEND_AUTO, + WINED3D_DECODER_BACKEND_VULKAN, + WINED3D_DECODER_BACKEND_VA, +}; + #define WINED3D_CSMT_ENABLE 0x00000001 #define WINED3D_CSMT_SERIALIZE 0x00000002 @@ -482,6 +489,7 @@ struct wined3d_settings unsigned int max_sm_cs; enum wined3d_renderer renderer; enum wined3d_shader_backend shader_backend; + enum wined3d_decoder_backend decoder_backend; bool check_float_constants; bool cb_access_map_w; bool ffp_hlsl; @@ -4520,6 +4528,7 @@ struct wined3d_decoder_ops }; extern const struct wined3d_decoder_ops wined3d_decoder_vk_ops; +extern const struct wined3d_decoder_ops wined3d_decoder_va_vk_ops; extern const struct wined3d_decoder_ops wined3d_null_decoder_ops; /* DirectDraw utility functions */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11535