From: Sil Vilerino Date: Tue, 29 Aug 2023 01:01:21 +0000 (-0400) Subject: d3d12: Extend video screen AV1 encode tile support checking X-Git-Tag: upstream/23.3.3~2351 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f857c9a96fe6a5fa6ea502892f11d398cdb7753a;p=platform%2Fupstream%2Fmesa.git d3d12: Extend video screen AV1 encode tile support checking Add fallback case to take into account driver reported tile restrictions if default hardcoded tile configurations are not supported by driver Reviewed-by: Tanner Van De Walle Part-of: --- diff --git a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp index a39c335..0976de5 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp @@ -327,7 +327,7 @@ d3d12_video_encode_supported_tile_structures(const D3D12_VIDEO_ENCODER_CODEC &co ID3D12VideoDevice3 *pD3D12VideoDevice, D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC maxRes, uint32_t& supportedSliceStructures, // out - uint32_t& tile_size_bytes_minus1 // out + D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT& av1TileSupport // out ) { // Assume no support and then add as queries succeed @@ -342,28 +342,70 @@ d3d12_video_encode_supported_tile_structures(const D3D12_VIDEO_ENCODER_CODEC &co capDataTilesSupport.Profile = profile; capDataTilesSupport.Level = level; capDataTilesSupport.FrameResolution = maxRes; // Query for worst case resolution - D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT av1TileSupport = { }; + av1TileSupport = { }; capDataTilesSupport.CodecSupport.DataSize = sizeof(av1TileSupport); capDataTilesSupport.CodecSupport.pAV1Support = &av1TileSupport; av1TileSupport.Use128SuperBlocks = false; // return units in 64x64 default size + constexpr UINT superBlockSize = 64u; - capDataTilesSupport.SubregionMode = - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION; - HRESULT hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, - &capDataTilesSupport, - sizeof(capDataTilesSupport)); - if(SUCCEEDED(hr) && capDataTilesSupport.IsSupported) - supportedSliceStructures |= (PIPE_VIDEO_CAP_SLICE_STRUCTURE_POWER_OF_TWO_ROWS | PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_ROWS | PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_MULTI_ROWS); - - capDataTilesSupport.SubregionMode = - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION; - hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, - &capDataTilesSupport, - sizeof(capDataTilesSupport)); - if(SUCCEEDED(hr) && capDataTilesSupport.IsSupported) - supportedSliceStructures |= (PIPE_VIDEO_CAP_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS | PIPE_VIDEO_CAP_SLICE_STRUCTURE_ARBITRARY_ROWS); - - tile_size_bytes_minus1 = av1TileSupport.TileSizeBytesMinus1; + { + capDataTilesSupport.SubregionMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION; + // Try with simple one tile request + av1TileSupport.TilesConfiguration.ColCount = 1; + av1TileSupport.TilesConfiguration.RowCount = 1; + av1TileSupport.TilesConfiguration.ColWidths[0] = (capDataTilesSupport.FrameResolution.Width / superBlockSize); + av1TileSupport.TilesConfiguration.RowHeights[0] = (capDataTilesSupport.FrameResolution.Height / superBlockSize); + HRESULT hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, + &capDataTilesSupport, + sizeof(capDataTilesSupport)); + if(SUCCEEDED(hr) && !capDataTilesSupport.IsSupported) { + // Try with minimum driver indicated params for the given resolution + // (ie. this could happen for high resolutions like 8K where AV1 max_tile_width (4096) is exceeded) + av1TileSupport.TilesConfiguration.ColCount = std::max(av1TileSupport.MinTileCols, 1u); + av1TileSupport.TilesConfiguration.RowCount = std::max(av1TileSupport.MinTileRows, 1u); + hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, + &capDataTilesSupport, + sizeof(capDataTilesSupport)); + } + + if(SUCCEEDED(hr) && capDataTilesSupport.IsSupported) + supportedSliceStructures |= (PIPE_VIDEO_CAP_SLICE_STRUCTURE_POWER_OF_TWO_ROWS | + PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_ROWS | + PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_MULTI_ROWS); + } + + { + capDataTilesSupport.SubregionMode = D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION; + // Try with simple one tile request + av1TileSupport.TilesConfiguration.ColCount = 1; + av1TileSupport.TilesConfiguration.RowCount = 1; + av1TileSupport.TilesConfiguration.ColWidths[0] = capDataTilesSupport.FrameResolution.Width; + av1TileSupport.TilesConfiguration.RowHeights[0] = capDataTilesSupport.FrameResolution.Height; + HRESULT hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, + &capDataTilesSupport, + sizeof(capDataTilesSupport)); + if(SUCCEEDED(hr) && !capDataTilesSupport.IsSupported) { + // Try with minimum driver indicated params for the given resolution + // (ie. this could happen for high resolutions like 8K where AV1 max_tile_width (4096) is exceeded) + av1TileSupport.TilesConfiguration.ColCount = std::max(av1TileSupport.MinTileCols, 1u); + av1TileSupport.TilesConfiguration.RowCount = std::max(av1TileSupport.MinTileRows, 1u); + // Try for uniform grid tiles + UINT tileWPixel = capDataTilesSupport.FrameResolution.Width / av1TileSupport.TilesConfiguration.ColCount; + UINT tileHPixel = capDataTilesSupport.FrameResolution.Height / av1TileSupport.TilesConfiguration.RowCount; + for (UINT i = 0; i < av1TileSupport.TilesConfiguration.ColCount; i++) + av1TileSupport.TilesConfiguration.ColWidths[i] = (tileWPixel / superBlockSize); + for (UINT j = 0; j < av1TileSupport.TilesConfiguration.RowCount; j++) + av1TileSupport.TilesConfiguration.RowHeights[j] = (tileHPixel / superBlockSize); + + hr = pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG, + &capDataTilesSupport, + sizeof(capDataTilesSupport)); + } + + if(SUCCEEDED(hr) && capDataTilesSupport.IsSupported) + supportedSliceStructures |= (PIPE_VIDEO_CAP_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS | + PIPE_VIDEO_CAP_SLICE_STRUCTURE_ARBITRARY_ROWS); + } } #endif @@ -459,11 +501,9 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec, DXGI_FORMAT encodeFormat, ID3D12VideoDevice3 *pD3D12VideoDevice, D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT codecSupport, - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE requestedSliceMode, D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 &capEncoderSupportData1, D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS &resolutionDepCaps) { - capEncoderSupportData1 = {}; capEncoderSupportData1.NodeIndex = 0; capEncoderSupportData1.Codec = argTargetCodec; capEncoderSupportData1.InputFormat = encodeFormat; @@ -478,13 +518,6 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec, capEncoderSupportData1.ResolutionsListCount = 1; capEncoderSupportData1.pResolutionList = &maxResolution; capEncoderSupportData1.MaxReferenceFramesInDPB = 1; -#if D3D12_PREVIEW_SDK_VERSION >= 711 - D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES sliceData = { }; - // Assume single tile for feature query support / entrypoint enumeration purposes - D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES tileData = { }; - tileData.ColCount = 1; - tileData.RowCount = 1; -#endif /* All codec structures must be declared outside the switch statement to be present in memory (stack scope) when calling CheckFeatureSupport below @@ -515,11 +548,6 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec, capEncoderSupportData1.CodecGopSequence.DataSize = sizeof(h264Gop); capEncoderSupportData1.CodecConfiguration.DataSize = sizeof(h264Config); capEncoderSupportData1.CodecConfiguration.pH264Config = &h264Config; - capEncoderSupportData1.SubregionFrameEncoding = requestedSliceMode; -#if D3D12_PREVIEW_SDK_VERSION >= 711 - capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(sliceData); - capEncoderSupportData1.SubregionFrameEncodingData.pSlicesPartition_H264 = &sliceData; -#endif } break; case D3D12_VIDEO_ENCODER_CODEC_HEVC: @@ -547,11 +575,6 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec, capEncoderSupportData1.CodecGopSequence.DataSize = sizeof(hevcGop); capEncoderSupportData1.CodecConfiguration.DataSize = sizeof(hevcConfig); capEncoderSupportData1.CodecConfiguration.pHEVCConfig = &hevcConfig; - capEncoderSupportData1.SubregionFrameEncoding = requestedSliceMode; -#if D3D12_PREVIEW_SDK_VERSION >= 711 - capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(sliceData); - capEncoderSupportData1.SubregionFrameEncodingData.pSlicesPartition_HEVC = &sliceData; -#endif } break; #if D3D12_PREVIEW_SDK_VERSION >= 711 @@ -583,10 +606,6 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec, av1Config.FeatureFlags = av1CodecSupport.RequiredFeatureFlags; capEncoderSupportData1.CodecConfiguration.DataSize = sizeof(av1Config); capEncoderSupportData1.CodecConfiguration.pAV1Config = &av1Config; - capEncoderSupportData1.SubregionFrameEncoding = requestedSliceMode; - capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(tileData); - capEncoderSupportData1.SubregionFrameEncodingData.pTilesPartition_AV1 = &tileData; - } break; #endif default: @@ -794,16 +813,21 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, profile, level, spD3D12VideoDevice.Get()); - D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1; + D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1 = {}; D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS resolutionDepCaps; + capEncoderSupportData1.SubregionFrameEncoding = (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME : + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME; +#if D3D12_PREVIEW_SDK_VERSION >= 711 + D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES sliceData = { }; + capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(sliceData); + capEncoderSupportData1.SubregionFrameEncodingData.pSlicesPartition_H264 = &sliceData; +#endif supportsProfile = supportsProfile && d3d12_video_encode_support_caps(codecDesc, maxRes, encodeFormat, spD3D12VideoDevice.Get(), d3d12_codec_support, - (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME - : D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME, capEncoderSupportData1, resolutionDepCaps); if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) @@ -957,16 +981,21 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, supportsProfile = supportsProfile && d3d12_video_encode_supported_resolution_range(codecDesc, minRes, maxRes, spD3D12VideoDevice.Get()); - D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1; + D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1 = {}; D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS resolutionDepCaps; + capEncoderSupportData1.SubregionFrameEncoding = (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME : + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME; +#if D3D12_PREVIEW_SDK_VERSION >= 711 + D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES sliceData = { }; + capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(sliceData); + capEncoderSupportData1.SubregionFrameEncodingData.pSlicesPartition_HEVC = &sliceData; +#endif supportsProfile = supportsProfile && d3d12_video_encode_support_caps(codecDesc, maxRes, encodeFormat, spD3D12VideoDevice.Get(), d3d12_codec_support, - (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME - : D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME, capEncoderSupportData1, resolutionDepCaps); if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) @@ -1178,30 +1207,34 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, supportsProfile = supportsProfile && d3d12_video_encode_supported_resolution_range(codecDesc, minRes, maxRes, spD3D12VideoDevice.Get()); - uint32_t tile_size_bytes_minus1 = 0; + D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT av1TileSupport = {}; d3d12_video_encode_supported_tile_structures(codecDesc, profDesc, maxLvl, spD3D12VideoDevice.Get(), maxRes, - supportedSliceStructures, // out - tile_size_bytes_minus1 // out + supportedSliceStructures, + av1TileSupport // out ); // Cannot pass pipe 2 bit-field as reference, use aux variable instead. - codecSupport.av1_support.features_ext2.bits.tile_size_bytes_minus1 = tile_size_bytes_minus1; + codecSupport.av1_support.features_ext2.bits.tile_size_bytes_minus1 = av1TileSupport.TileSizeBytesMinus1; DXGI_FORMAT encodeFormat = d3d12_convert_pipe_video_profile_to_dxgi_format(profile); - D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1; + D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1 capEncoderSupportData1 = {}; D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS resolutionDepCaps; + capEncoderSupportData1.SubregionFrameEncoding = (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME : + D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION; + + capEncoderSupportData1.SubregionFrameEncodingData.DataSize = sizeof(av1TileSupport.TilesConfiguration); + capEncoderSupportData1.SubregionFrameEncodingData.pTilesPartition_AV1 = &av1TileSupport.TilesConfiguration; + supportsProfile = supportsProfile && d3d12_video_encode_support_caps(codecDesc, maxRes, encodeFormat, spD3D12VideoDevice.Get(), d3d12_codec_support, - (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) ? - D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_FULL_FRAME - : D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION, capEncoderSupportData1, resolutionDepCaps); if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE)