From 495ed45d056cc4ae88c95b5587732d87382e93a1 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 12 Jul 2020 01:22:55 +0900 Subject: [PATCH] d3d11decoder: Disable zero-copy for Qualcomm devices Qualcomm driver looks buggy in zero-copy scenario. Even if we disable zero-copy, device-to-device memory copy will be used with d3d11videosink which should be fast enough. Part-of: --- sys/d3d11/gstd3d11decoder.c | 27 ++++++++++++++++++++------- sys/d3d11/gstd3d11utils.c | 31 +++++++++++++++++++++++++------ sys/d3d11/gstd3d11utils.h | 12 +++++++++++- sys/d3d11/gstd3d11window.cpp | 3 ++- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/sys/d3d11/gstd3d11decoder.c b/sys/d3d11/gstd3d11decoder.c index e211f48c38..1743e96cda 100644 --- a/sys/d3d11/gstd3d11decoder.c +++ b/sys/d3d11/gstd3d11decoder.c @@ -93,7 +93,7 @@ struct _GstD3D11DecoderPrivate GUID decoder_profile; /* For device specific workaround */ - gboolean is_xbox_device; + gboolean can_direct_rendering; /* for internal shader */ GstD3D11ColorConverter *converter; @@ -636,6 +636,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec, gint i; guint aligned_width, aligned_height; guint alignment; + GstD3D11DeviceVendor vendor; g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE); g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, FALSE); @@ -676,7 +677,22 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec, gst_d3d11_decoder_reset_unlocked (decoder); - priv->is_xbox_device = gst_d3d11_is_xbox_device (priv->device); + priv->can_direct_rendering = TRUE; + + vendor = gst_d3d11_get_device_vendor (priv->device); + switch (vendor) { + case GST_D3D11_DEVICE_VENDOR_XBOX: + case GST_D3D11_DEVICE_VENDOR_QUALCOMM: + /* FIXME: Need to figure out Xbox device's behavior + * https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312 + * + * Qualcomm driver seems to be buggy in zero-copy scenario + */ + priv->can_direct_rendering = FALSE; + break; + default: + break; + } /* NOTE: other dxva implementations (ffmpeg and vlc) do this * and they say the required alignment were mentioned by dxva spec. @@ -686,7 +702,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec, switch (codec) { case GST_D3D11_CODEC_H265: /* See directx_va_Setup() impl. in vlc */ - if (!priv->is_xbox_device) + if (vendor != GST_D3D11_DEVICE_VENDOR_XBOX) alignment = 128; else alignment = 16; @@ -1605,10 +1621,7 @@ gst_d3d11_decoder_supports_direct_rendering (GstD3D11Decoder * decoder) priv = decoder->priv; - /* FIXME: Need to figure out Xbox device's behavior - * https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312 - */ - return !priv->is_xbox_device; + return priv->can_direct_rendering; } /* Keep sync with chromium and keep in sorted order. diff --git a/sys/d3d11/gstd3d11utils.c b/sys/d3d11/gstd3d11utils.c index d306403a6a..9e342c08f4 100644 --- a/sys/d3d11/gstd3d11utils.c +++ b/sys/d3d11/gstd3d11utils.c @@ -346,25 +346,44 @@ gst_d3d11_is_windows_8_or_greater (void) return ret; } -gboolean -gst_d3d11_is_xbox_device (GstD3D11Device * device) +GstD3D11DeviceVendor +gst_d3d11_get_device_vendor (GstD3D11Device * device) { guint device_id = 0; guint vendor_id = 0; gchar *desc = NULL; - gboolean ret = FALSE; + GstD3D11DeviceVendor vendor = GST_D3D11_DEVICE_VENDOR_UNKNOWN; g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE); g_object_get (device, "device-id", &device_id, "vendor-id", &vendor_id, "description", &desc, NULL); - if (device_id == 0 && vendor_id == 0 && desc && g_strrstr (desc, "SraKmd")) - ret = TRUE; + switch (vendor_id) { + case 0: + if (device_id == 0 && desc && g_strrstr (desc, "SraKmd")) + vendor = GST_D3D11_DEVICE_VENDOR_XBOX; + break; + case 0x1002: + case 0x1022: + vendor = GST_D3D11_DEVICE_VENDOR_AMD; + break; + case 0x8086: + vendor = GST_D3D11_DEVICE_VENDOR_INTEL; + break; + case 0x10de: + vendor = GST_D3D11_DEVICE_VENDOR_NVIDIA; + break; + case 0x4d4f4351: + vendor = GST_D3D11_DEVICE_VENDOR_QUALCOMM; + break; + default: + break; + } g_free (desc); - return ret; + return vendor; } static gchar * diff --git a/sys/d3d11/gstd3d11utils.h b/sys/d3d11/gstd3d11utils.h index ab3618f3c9..5aa37fbe8e 100644 --- a/sys/d3d11/gstd3d11utils.h +++ b/sys/d3d11/gstd3d11utils.h @@ -27,6 +27,16 @@ G_BEGIN_DECLS +typedef enum +{ + GST_D3D11_DEVICE_VENDOR_UNKNOWN = 0, + GST_D3D11_DEVICE_VENDOR_AMD, + GST_D3D11_DEVICE_VENDOR_INTEL, + GST_D3D11_DEVICE_VENDOR_NVIDIA, + GST_D3D11_DEVICE_VENDOR_QUALCOMM, + GST_D3D11_DEVICE_VENDOR_XBOX, +} GstD3D11DeviceVendor; + gboolean gst_d3d11_handle_set_context (GstElement * element, GstContext * context, gint adapter, @@ -42,7 +52,7 @@ gboolean gst_d3d11_ensure_element_data (GstElement * element, gboolean gst_d3d11_is_windows_8_or_greater (void); -gboolean gst_d3d11_is_xbox_device (GstD3D11Device * device); +GstD3D11DeviceVendor gst_d3d11_get_device_vendor (GstD3D11Device * device); gboolean _gst_d3d11_result (HRESULT hr, GstD3D11Device * device, diff --git a/sys/d3d11/gstd3d11window.cpp b/sys/d3d11/gstd3d11window.cpp index b3a72cbad7..a6561ee574 100644 --- a/sys/d3d11/gstd3d11window.cpp +++ b/sys/d3d11/gstd3d11window.cpp @@ -668,7 +668,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width, /* FIXME: need to verify video processor on Xbox * https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312 */ - if (!gst_d3d11_is_xbox_device (window->device)) { + if (gst_d3d11_get_device_vendor (window->device) != + GST_D3D11_DEVICE_VENDOR_XBOX) { window->processor = gst_d3d11_video_processor_new (window->device, GST_VIDEO_INFO_WIDTH (&window->info),