From 2848af5618fa823571cf4ec8cc2a4580d37f1648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Mon, 19 Aug 2024 17:49:34 +0200 Subject: [PATCH] vf_d3d11vpp: add support for Intel VSR and NVIDIA RTX scaling modes Adds `--vf=d3d11vpp=scaling-mode` to control which extensions should be enabled. Fixes: #11390 Co-authored-by: xc --- .../d3d11va-scaling-mode.txt | 1 + DOCS/man/vf.rst | 12 ++ video/filter/vf_d3d11vpp.c | 113 ++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 DOCS/interface-changes/d3d11va-scaling-mode.txt diff --git a/DOCS/interface-changes/d3d11va-scaling-mode.txt b/DOCS/interface-changes/d3d11va-scaling-mode.txt new file mode 100644 index 0000000000..bce1f4cdef --- /dev/null +++ b/DOCS/interface-changes/d3d11va-scaling-mode.txt @@ -0,0 +1 @@ +add `--vf=d3d11vpp=scaling-mode` diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst index 1901e2fc4c..6a5a7ce344 100644 --- a/DOCS/man/vf.rst +++ b/DOCS/man/vf.rst @@ -694,6 +694,18 @@ Available mpv-only filters are: Whether deinterlacing is enabled (default: no). ``scale`` Scaling factor for the video frames (default: 1.0). + ``scaling-mode=`` + Select the scaling mode to be used. Note that this only enables the + appropriate processing extensions; whether it actually works or not + depends on your hardware and the settings in your GPU driver's control + panel (default: standard). + + standard + Default scaling mode as decided by d3d11vpp implementation. + intel + Intel Video Super Resolution. + nvidia + NVIDIA RTX Super Resolution. ``interlaced-only=`` If ``yes``, only deinterlace frames marked as interlaced (default: no). ``mode=`` diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c index c46159c326..402075b781 100644 --- a/video/filter/vf_d3d11vpp.c +++ b/video/filter/vf_d3d11vpp.c @@ -42,9 +42,40 @@ #define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE 0x10 #define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION 0x20 +// For video procesor extensions identifiers reference see: +// https://chromium.googlesource.com/chromium/src/+/5f354f38/ui/gl/swap_chain_presenter.cc + +#ifndef NVIDIA_PPE_INTERFACE_GUID +DEFINE_GUID(NVIDIA_PPE_INTERFACE_GUID, + 0xd43ce1b3, 0x1f4b, 0x48ac, 0xba, 0xee, + 0xc3, 0xc2, 0x53, 0x75, 0xe6, 0xf7); +#endif + +#ifndef INTEL_VPE_INTERFACE_GUID +DEFINE_GUID(INTEL_VPE_INTERFACE_GUID, + 0xedd1d4b9, 0x8659, 0x4cbc, 0xa4, 0xd6, + 0x98, 0x31, 0xa2, 0x16, 0x3a, 0xc3); +#endif + +static const unsigned int intel_vpe_fn_version = 0x1; +static const unsigned int intel_vpe_version = 0x3; + +static const unsigned int intel_vpe_fn_scaling = 0x37; +static const unsigned int intel_vpe_scaling_vsr = 0x2; + +static const unsigned int intel_vpe_fn_mode = 0x20; +static const unsigned int intel_vpe_mode_preproc = 0x1; + +enum scaling_mode { + SCALING_BASIC, + SCALING_INTEL_VSR, + SCALING_NVIDIA_RTX, +}; + struct opts { bool deint_enabled; float scale; + int scaling_mode; bool interlaced_only; int mode; int field_parity; @@ -135,6 +166,74 @@ static void destroy_video_proc(struct mp_filter *vf) p->vp_enum = NULL; } +static void enable_nvidia_rtx_extension(struct mp_filter *vf) +{ + struct priv *p = vf->priv; + + struct nvidia_ext { + unsigned int version; + unsigned int method; + unsigned int enable; + } ext = {1, 2, 1}; + + HRESULT hr = ID3D11VideoContext_VideoProcessorSetStreamExtension(p->video_ctx, + p->video_proc, + 0, + &NVIDIA_PPE_INTERFACE_GUID, + sizeof(ext), + &ext); + + if (FAILED(hr)) { + MP_WARN(vf, "Failed to enable NVIDIA RTX Super Resolution: %s\n", mp_HRESULT_to_str(hr)); + } else { + MP_VERBOSE(vf, "NVIDIA RTX Super Resolution enabled\n"); + } +} + +static void enable_intel_vsr_extension(struct mp_filter *vf) +{ + struct priv *p = vf->priv; + + struct intel_vpe_ext { + unsigned int function; + const void* param; + } ext; + + ext = (struct intel_vpe_ext){intel_vpe_fn_version, &intel_vpe_version}; + HRESULT hr = ID3D11VideoContext_VideoProcessorSetOutputExtension(p->video_ctx, + p->video_proc, + &INTEL_VPE_INTERFACE_GUID, + sizeof(ext), + &ext); + if (FAILED(hr)) + goto failed; + + ext = (struct intel_vpe_ext){intel_vpe_fn_mode, &intel_vpe_mode_preproc}; + hr = ID3D11VideoContext_VideoProcessorSetOutputExtension(p->video_ctx, + p->video_proc, + &INTEL_VPE_INTERFACE_GUID, + sizeof(ext), + &ext); + if (FAILED(hr)) + goto failed; + + ext = (struct intel_vpe_ext){intel_vpe_fn_scaling, &intel_vpe_scaling_vsr}; + hr = ID3D11VideoContext_VideoProcessorSetStreamExtension(p->video_ctx, + p->video_proc, + 0, + &INTEL_VPE_INTERFACE_GUID, + sizeof(ext), + &ext); + if (FAILED(hr)) + goto failed; + + MP_VERBOSE(vf, "Intel Video Super Resolution enabled\n"); + return; + +failed: + MP_WARN(vf, "Failed to enable Intel Video Super Resolution: %s\n", mp_HRESULT_to_str(hr)); +} + static int recreate_video_proc(struct mp_filter *vf) { struct priv *p = vf->priv; @@ -222,6 +321,15 @@ static int recreate_video_proc(struct mp_filter *vf) p->video_proc, &csp); + switch (p->opts->scaling_mode) { + case SCALING_INTEL_VSR: + enable_intel_vsr_extension(vf); + break; + case SCALING_NVIDIA_RTX: + enable_nvidia_rtx_extension(vf); + break; + } + return 0; fail: destroy_video_proc(vf); @@ -499,6 +607,10 @@ fail: static const m_option_t vf_opts_fields[] = { {"deint", OPT_BOOL(deint_enabled)}, {"scale", OPT_FLOAT(scale)}, + {"scaling-mode", OPT_CHOICE(scaling_mode, + {"standard", SCALING_BASIC}, + {"intel", SCALING_INTEL_VSR}, + {"nvidia", SCALING_NVIDIA_RTX})}, {"interlaced-only", OPT_BOOL(interlaced_only)}, {"mode", OPT_CHOICE(mode, {"blend", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND}, @@ -522,6 +634,7 @@ const struct mp_user_filter_entry vf_d3d11vpp = { .priv_defaults = &(const OPT_BASE_STRUCT) { .deint_enabled = false, .scale = 1.0, + .scaling_mode = SCALING_BASIC, .mode = 0, .field_parity = MP_FIELD_PARITY_AUTO, },