Mesa (main): d3d12: Enable VPP rotation, flip, alpha blend, crop, scaling via pipe_video_codec::process_frame
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jul 21 23:05:21 UTC 2022
Module: Mesa
Branch: main
Commit: 948c03bf58b73f904fb9abe3814b0f830328168f
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=948c03bf58b73f904fb9abe3814b0f830328168f
Author: Sil Vilerino <sivileri at microsoft.com>
Date: Fri Jul 15 08:04:49 2022 -0400
d3d12: Enable VPP rotation, flip, alpha blend, crop, scaling via pipe_video_codec::process_frame
Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17557>
---
src/gallium/drivers/d3d12/d3d12_context.cpp | 3 +
src/gallium/drivers/d3d12/d3d12_video_screen.cpp | 160 +++++++++++++++++++++++
2 files changed, 163 insertions(+)
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 84023c43cdd..1b84a68d23f 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -37,6 +37,7 @@
#ifdef HAVE_GALLIUM_D3D12_VIDEO
#include "d3d12_video_dec.h"
#include "d3d12_video_enc.h"
+#include "d3d12_video_proc.h"
#include "d3d12_video_buffer.h"
#endif
#include "util/u_atomic.h"
@@ -2407,6 +2408,8 @@ d3d12_video_create_codec(struct pipe_context *context,
return d3d12_video_encoder_create_encoder(context, templat);
} else if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
return d3d12_video_create_decoder(context, templat);
+ } else if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
+ return d3d12_video_processor_create(context, templat);
} else {
debug_printf("D3D12: Unsupported video codec entrypoint %d\n", templat->entrypoint);
return nullptr;
diff --git a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp
index cd1fa052e53..a5b8cd323b4 100644
--- a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp
@@ -542,6 +542,164 @@ d3d12_screen_get_video_param_decode(struct pipe_screen *pscreen,
}
}
+
+static bool
+d3d12_has_video_process_support(struct pipe_screen *pscreen, D3D12_FEATURE_DATA_VIDEO_PROCESS_SUPPORT &supportCaps)
+{
+ ComPtr<ID3D12VideoDevice2> spD3D12VideoDevice;
+ struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
+ if (FAILED(pD3D12Screen->dev->QueryInterface(IID_PPV_ARGS(spD3D12VideoDevice.GetAddressOf())))) {
+ // No video encode support in underlying d3d12 device (needs ID3D12VideoDevice2)
+ return false;
+ }
+
+ D3D12_FEATURE_DATA_VIDEO_FEATURE_AREA_SUPPORT VideoFeatureAreaSupport = {};
+ if (FAILED(spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_FEATURE_AREA_SUPPORT,
+ &VideoFeatureAreaSupport,
+ sizeof(VideoFeatureAreaSupport)))) {
+ return false;
+ }
+
+ struct ResolStruct {
+ uint Width;
+ uint Height;
+ };
+
+ ResolStruct resolutionsList[] = {
+ { 8192, 8192 }, // 8k
+ { 8192, 4320 }, // 8k - alternative
+ { 7680, 4800 }, // 8k - alternative
+ { 7680, 4320 }, // 8k - alternative
+ { 4096, 2304 }, // 2160p (4K)
+ { 4096, 2160 }, // 2160p (4K) - alternative
+ { 2560, 1440 }, // 1440p
+ { 1920, 1200 }, // 1200p
+ { 1920, 1080 }, // 1080p
+ { 1280, 720 }, // 720p
+ { 800, 600 },
+ };
+
+ uint32_t idxResol = 0;
+ bool bSupportsAny = false;
+ while ((idxResol < ARRAY_SIZE(resolutionsList)) && !bSupportsAny) {
+ supportCaps.InputSample.Width = resolutionsList[idxResol].Width;
+ supportCaps.InputSample.Height = resolutionsList[idxResol].Height;
+ if (SUCCEEDED(spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_PROCESS_SUPPORT, &supportCaps, sizeof(supportCaps)))) {
+ bSupportsAny = ((supportCaps.SupportFlags & D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) != 0) ;
+ }
+ idxResol++;
+ }
+
+ return VideoFeatureAreaSupport.VideoProcessSupport && bSupportsAny;
+}
+
+static int
+d3d12_screen_get_video_param_postproc(struct pipe_screen *pscreen,
+ enum pipe_video_profile profile,
+ enum pipe_video_entrypoint entrypoint,
+ enum pipe_video_cap param)
+{
+ switch (param) {
+ case PIPE_VIDEO_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_VIDEO_CAP_MAX_WIDTH:
+ case PIPE_VIDEO_CAP_MAX_HEIGHT:
+ case PIPE_VIDEO_CAP_SUPPORTED:
+ case PIPE_VIDEO_CAP_PREFERED_FORMAT:
+ case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
+ case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
+ case PIPE_VIDEO_CAP_VPP_MAX_INPUT_WIDTH:
+ case PIPE_VIDEO_CAP_VPP_MAX_INPUT_HEIGHT:
+ case PIPE_VIDEO_CAP_VPP_MIN_INPUT_WIDTH:
+ case PIPE_VIDEO_CAP_VPP_MIN_INPUT_HEIGHT:
+ case PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_WIDTH:
+ case PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_HEIGHT:
+ case PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_WIDTH:
+ case PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_HEIGHT:
+ case PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES:
+ case PIPE_VIDEO_CAP_VPP_BLEND_MODES:
+ {
+ // Assume defaults for now, we don't have the input args passed by get_video_param to be accurate here.
+ const D3D12_VIDEO_FIELD_TYPE FieldType = D3D12_VIDEO_FIELD_TYPE_NONE;
+ const D3D12_VIDEO_FRAME_STEREO_FORMAT StereoFormat = D3D12_VIDEO_FRAME_STEREO_FORMAT_NONE;
+ const DXGI_RATIONAL FrameRate = { 30, 1 };
+ const DXGI_FORMAT InputFormat = DXGI_FORMAT_NV12;
+ const DXGI_COLOR_SPACE_TYPE InputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
+ const DXGI_FORMAT OutputFormat = DXGI_FORMAT_NV12;
+ const DXGI_COLOR_SPACE_TYPE OutputColorSpace = DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
+ const UINT Width = 1280;
+ const UINT Height = 720;
+ D3D12_FEATURE_DATA_VIDEO_PROCESS_SUPPORT supportCaps =
+ {
+ 0, // NodeIndex
+ { Width, Height, { InputFormat, InputColorSpace } },
+ FieldType,
+ StereoFormat,
+ FrameRate,
+ { OutputFormat, OutputColorSpace },
+ StereoFormat,
+ FrameRate,
+ };
+
+ if (d3d12_has_video_process_support(pscreen, supportCaps)) {
+ if (param == PIPE_VIDEO_CAP_SUPPORTED) {
+ return true;
+ } else if (param == PIPE_VIDEO_CAP_PREFERED_FORMAT) {
+ return PIPE_FORMAT_NV12;
+ } else if (param == PIPE_VIDEO_CAP_SUPPORTS_INTERLACED) {
+ return false;
+ } else if (param == PIPE_VIDEO_CAP_MAX_WIDTH) {
+ return supportCaps.InputSample.Width;
+ } else if (param == PIPE_VIDEO_CAP_MAX_HEIGHT) {
+ return supportCaps.InputSample.Height;
+ } else if (param == PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE) {
+ return true;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MAX_INPUT_WIDTH) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MaxWidth;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MAX_INPUT_HEIGHT) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MaxHeight;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MIN_INPUT_WIDTH) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MinWidth;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MIN_INPUT_HEIGHT) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MinHeight;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_WIDTH) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MaxWidth;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_HEIGHT) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MaxHeight;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_WIDTH) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MinWidth;
+ } else if (param == PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_HEIGHT) {
+ return supportCaps.ScaleSupport.OutputSizeRange.MinHeight;
+ } else if (param == PIPE_VIDEO_CAP_VPP_BLEND_MODES) {
+ uint32_t blend_modes = PIPE_VIDEO_VPP_BLEND_MODE_NONE;
+ if (((supportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_BLENDING) != 0)
+ && ((supportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ALPHA_FILL) != 0))
+ {
+ blend_modes |= PIPE_VIDEO_VPP_BLEND_MODE_GLOBAL_ALPHA;
+ }
+ return blend_modes;
+ } else if (param == PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES) {
+ uint32_t orientation_modes = PIPE_VIDEO_VPP_ORIENTATION_DEFAULT;
+ if((supportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_FLIP) != 0) {
+ orientation_modes |= PIPE_VIDEO_VPP_FLIP_HORIZONTAL;
+ orientation_modes |= PIPE_VIDEO_VPP_FLIP_VERTICAL;
+ }
+
+ if((supportCaps.FeatureSupport & D3D12_VIDEO_PROCESS_FEATURE_FLAG_ROTATION) != 0) {
+ orientation_modes |= PIPE_VIDEO_VPP_ROTATION_90;
+ orientation_modes |= PIPE_VIDEO_VPP_ROTATION_180;
+ orientation_modes |= PIPE_VIDEO_VPP_ROTATION_270;
+ }
+ return orientation_modes;
+ }
+ }
+ return 0;
+ } break;
+ default:
+ return 0;
+ }
+}
+
static int
d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
enum pipe_video_profile profile,
@@ -613,6 +771,8 @@ d3d12_screen_get_video_param(struct pipe_screen *pscreen,
return d3d12_screen_get_video_param_decode(pscreen, profile, entrypoint, param);
} else if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
return d3d12_screen_get_video_param_encode(pscreen, profile, entrypoint, param);
+ } else if (entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
+ return d3d12_screen_get_video_param_postproc(pscreen, profile, entrypoint, param);
}
return 0;
}
More information about the mesa-commit
mailing list