uint32_t level;
};
-static d3d12_video_resolution_to_level_mapping_entry
-get_max_level_resolution_video_decode_support(D3D12_VIDEO_DECODE_CONFIGURATION decoderConfig,
+static void
+get_level_resolution_video_decode_support(D3D12_VIDEO_DECODE_CONFIGURATION decoderConfig,
DXGI_FORMAT format,
struct pipe_screen *pscreen,
bool &outSupportAny,
- D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT &outSupportedConfig)
+ D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT &outMaxSupportedConfig,
+ d3d12_video_resolution_to_level_mapping_entry &outMaxResol,
+ d3d12_video_resolution_to_level_mapping_entry &outMinResol)
{
- d3d12_video_resolution_to_level_mapping_entry supportedResult = {};
outSupportAny = false;
- outSupportedConfig = {};
+ outMaxSupportedConfig = {};
+ outMinResol = {};
+ outMaxResol = {};
ComPtr<ID3D12VideoDevice> spD3D12VideoDevice;
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
if (FAILED(pD3D12Screen->dev->QueryInterface(IID_PPV_ARGS(spD3D12VideoDevice.GetAddressOf())))) {
// No video support in underlying d3d12 device (decode needs ID3D12VideoDevice)
- return supportedResult;
+ return;
}
d3d12_video_resolution_to_level_mapping_entry resolutionsLevelList[] = {
{ { 1920, 1080 }, 42 }, // 1080p
{ { 1280, 720 }, 4 }, // 720p
{ { 800, 600 }, 31 },
+ { { 352, 480 }, 3 },
+ { { 352, 240 }, 2 },
+ { { 176, 144 }, 11 },
+ { { 128, 96 }, 11 },
};
D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT decodeSupport = {};
decodeSupport.DecodeFormat = format;
uint32_t idxResol = 0;
- while ((idxResol < ARRAY_SIZE(resolutionsLevelList)) && !outSupportAny) {
+ while (idxResol < ARRAY_SIZE(resolutionsLevelList)) {
decodeSupport.Width = resolutionsLevelList[idxResol].resolution.Width;
decodeSupport.Height = resolutionsLevelList[idxResol].resolution.Height;
if (SUCCEEDED(spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_DECODE_SUPPORT,
&decodeSupport,
sizeof(decodeSupport)))) {
-
if (((decodeSupport.SupportFlags & D3D12_VIDEO_DECODE_SUPPORT_FLAG_SUPPORTED) != 0) ||
decodeSupport.DecodeTier > D3D12_VIDEO_DECODE_TIER_NOT_SUPPORTED) {
- outSupportAny = true;
- outSupportedConfig = decodeSupport;
- supportedResult = resolutionsLevelList[idxResol];
+ // Save the first (maximum)
+ if(!outSupportAny) {
+ outMaxSupportedConfig = decodeSupport;
+ outMaxResol = resolutionsLevelList[idxResol];
+ outSupportAny = true;
+ }
+
+ // Keep saving the other supported values to get the minimum
+ outMinResol = resolutionsLevelList[idxResol];
}
}
-
idxResol++;
}
-
- return supportedResult;
}
static bool
}
static bool
-d3d12_video_encode_max_supported_resolution(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec,
- D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC &maxResolution,
- ID3D12VideoDevice3 *pD3D12VideoDevice)
+d3d12_video_encode_supported_resolution_range(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec,
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC &minResolution,
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC &maxResolution,
+ ID3D12VideoDevice3 *pD3D12VideoDevice)
{
D3D12_FEATURE_DATA_VIDEO_ENCODER_OUTPUT_RESOLUTION_RATIOS_COUNT capResRatiosCountData = { 0, argTargetCodec, 0 };
return false;
}
+ minResolution = capOutputResolutionData.MinResolutionSupported;
maxResolution = capOutputResolutionData.MaxResolutionSupported;
return true;
d3d12_has_video_encode_support(struct pipe_screen *pscreen,
enum pipe_video_profile profile,
uint32_t &maxLvlSpec,
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC &minRes,
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC &maxRes,
uint32_t &maxSlices,
uint32_t &supportedSliceStructures,
DXGI_FORMAT encodeFormat = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
supportsProfile = supportsProfile &&
- d3d12_video_encode_max_supported_resolution(codecDesc, maxRes, spD3D12VideoDevice.Get());
+ d3d12_video_encode_supported_resolution_range(codecDesc, minRes, maxRes, spD3D12VideoDevice.Get());
D3D12_VIDEO_ENCODER_PROFILE_DESC profile;
profile.pH264Profile = &profH264;
DXGI_FORMAT encodeFormat = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
supportsProfile = supportsProfile &&
- d3d12_video_encode_max_supported_resolution(codecDesc, maxRes, spD3D12VideoDevice.Get());
+ d3d12_video_encode_supported_resolution_range(codecDesc, minRes, maxRes, spD3D12VideoDevice.Get());
if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE)
maxSlices = 0;
case PIPE_VIDEO_CAP_MAX_WIDTH:
case PIPE_VIDEO_CAP_MAX_HEIGHT:
case PIPE_VIDEO_CAP_MAX_LEVEL:
+ case PIPE_VIDEO_CAP_MIN_WIDTH:
+ case PIPE_VIDEO_CAP_MIN_HEIGHT:
case PIPE_VIDEO_CAP_SUPPORTED:
{
if (d3d12_has_video_decode_support(pscreen, profile)) {
D3D12_BITSTREAM_ENCRYPTION_TYPE_NONE,
D3D12_VIDEO_FRAME_CODED_INTERLACE_TYPE_NONE };
- d3d12_video_resolution_to_level_mapping_entry bestSupportedConfig =
- get_max_level_resolution_video_decode_support(decoderConfig,
+ d3d12_video_resolution_to_level_mapping_entry lowestSupportedConfig = {};
+ d3d12_video_resolution_to_level_mapping_entry bestSupportedConfig = {};
+ get_level_resolution_video_decode_support(decoderConfig,
format,
pscreen,
supportAny,
- outSupportedConfig);
+ outSupportedConfig,
+ bestSupportedConfig,
+ lowestSupportedConfig);
if (supportAny) {
if (param == PIPE_VIDEO_CAP_MAX_WIDTH) {
return bestSupportedConfig.resolution.Width;
} else if (param == PIPE_VIDEO_CAP_MAX_HEIGHT) {
return bestSupportedConfig.resolution.Height;
+ } else if (param == PIPE_VIDEO_CAP_MIN_WIDTH) {
+ return lowestSupportedConfig.resolution.Width;
+ } else if (param == PIPE_VIDEO_CAP_MIN_HEIGHT) {
+ return lowestSupportedConfig.resolution.Height;
} else if (param == PIPE_VIDEO_CAP_MAX_LEVEL) {
return bestSupportedConfig.level;
} else if (param == PIPE_VIDEO_CAP_SUPPORTED) {
return true;
case PIPE_VIDEO_CAP_SUPPORTS_CONTIGUOUS_PLANES_MAP:
return true;
- break;
default:
debug_printf("[d3d12_screen_get_video_param] unknown video param: %d\n", param);
return 0;
static bool
-d3d12_has_video_process_support(struct pipe_screen *pscreen, D3D12_FEATURE_DATA_VIDEO_PROCESS_SUPPORT &supportCaps)
+d3d12_has_video_process_support(struct pipe_screen *pscreen,
+ D3D12_FEATURE_DATA_VIDEO_PROCESS_SUPPORT &supportCaps,
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC& outMinSupportedInput,
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC& outMaxSupportedInput)
{
ComPtr<ID3D12VideoDevice2> spD3D12VideoDevice;
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
return false;
}
- struct ResolStruct {
- uint Width;
- uint Height;
- };
-
- ResolStruct resolutionsList[] = {
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC resolutionsList[] = {
{ 8192, 8192 }, // 8k
{ 8192, 4320 }, // 8k - alternative
{ 7680, 4800 }, // 8k - alternative
{ 1920, 1080 }, // 1080p
{ 1280, 720 }, // 720p
{ 800, 600 },
+ { 352, 480 },
+ { 352, 240 },
+ { 176, 144 },
+ { 128, 128 },
+ { 96, 96 },
+ { 64, 64 },
+ { 32, 32 },
+ { 16, 16 },
+ { 8, 8 },
+ { 4, 4 },
+ { 2, 2 },
+ { 1, 1 },
};
+ outMinSupportedInput = {};
+ outMaxSupportedInput = {};
uint32_t idxResol = 0;
bool bSupportsAny = false;
- while ((idxResol < ARRAY_SIZE(resolutionsList)) && !bSupportsAny) {
+ while (idxResol < ARRAY_SIZE(resolutionsList)) {
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) ;
+ if ((supportCaps.SupportFlags & D3D12_VIDEO_PROCESS_SUPPORT_FLAG_SUPPORTED) != 0)
+ {
+ // Save the first (maximum)
+ if(!bSupportsAny) {
+ outMaxSupportedInput = resolutionsList[idxResol];
+ bSupportsAny = true;
+ }
+
+ // Keep saving the other supported values to get the minimum
+ outMinSupportedInput = resolutionsList[idxResol];
+ }
}
idxResol++;
}
return 1;
case PIPE_VIDEO_CAP_MAX_WIDTH:
case PIPE_VIDEO_CAP_MAX_HEIGHT:
+ case PIPE_VIDEO_CAP_MIN_WIDTH:
+ case PIPE_VIDEO_CAP_MIN_HEIGHT:
case PIPE_VIDEO_CAP_SUPPORTED:
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
FrameRate,
};
- if (d3d12_has_video_process_support(pscreen, supportCaps)) {
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC minSupportedInput = {};
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC maxSupportedInput = {};
+ if (d3d12_has_video_process_support(pscreen, supportCaps, minSupportedInput, maxSupportedInput)) {
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_MIN_WIDTH) {
+ return minSupportedInput.Width;
+ } else if (param == PIPE_VIDEO_CAP_MIN_HEIGHT) {
+ return minSupportedInput.Height;
} else if (param == PIPE_VIDEO_CAP_MAX_WIDTH) {
- return supportCaps.InputSample.Width;
+ return maxSupportedInput.Width;
} else if (param == PIPE_VIDEO_CAP_MAX_HEIGHT) {
- return supportCaps.InputSample.Height;
+ return maxSupportedInput.Height;
} else if (param == PIPE_VIDEO_CAP_SUPPORTS_CONTIGUOUS_PLANES_MAP) {
return true;
} else if (param == PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE) {
enum pipe_video_cap param)
{
uint32_t maxLvlEncode = 0u;
+ D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC minResEncode = {};
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC maxResEncode = {};
uint32_t maxSlices = 0u;
uint32_t supportedSliceStructures = 0u;
return 1;
case PIPE_VIDEO_CAP_MAX_WIDTH:
case PIPE_VIDEO_CAP_MAX_HEIGHT:
+ case PIPE_VIDEO_CAP_MIN_WIDTH:
+ case PIPE_VIDEO_CAP_MIN_HEIGHT:
case PIPE_VIDEO_CAP_MAX_LEVEL:
case PIPE_VIDEO_CAP_SUPPORTED:
case PIPE_VIDEO_CAP_ENC_MAX_SLICES_PER_FRAME:
if (d3d12_has_video_encode_support(pscreen,
profile,
maxLvlEncode,
+ minResEncode,
maxResEncode,
maxSlices,
supportedSliceStructures,
return maxResEncode.Width;
} else if (param == PIPE_VIDEO_CAP_MAX_HEIGHT) {
return maxResEncode.Height;
+ } else if (param == PIPE_VIDEO_CAP_MIN_WIDTH) {
+ return minResEncode.Width;
+ } else if (param == PIPE_VIDEO_CAP_MIN_HEIGHT) {
+ return minResEncode.Height;
} else if (param == PIPE_VIDEO_CAP_MAX_LEVEL) {
return maxLvlEncode;
} else if (param == PIPE_VIDEO_CAP_SUPPORTED) {