mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-27 12:14:10 +08:00
d3d12: Enable VPP rotation, flip, alpha blend, crop, scaling via pipe_video_codec::process_frame
Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17557>
This commit is contained in:
parent
323cf5a68d
commit
948c03bf58
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user