From 4a62f8bc75f4e2a2792dc15dae0c73a2033133cf Mon Sep 17 00:00:00 2001 From: Sil Vilerino Date: Fri, 28 Feb 2025 14:13:31 -0500 Subject: [PATCH] d3d12: Cache the texture array cap requirement in encoder creation for calls to d3d12_video_create_dpb_buffer Previously, the caps were not queried until after the first DPB buffer was created. That causes the AOT path to be triggered even when the device does report a requirement for texture array. Tested-by: Benjamin Cheng Reviewed-by: Benjamin Cheng Part-of: --- src/gallium/drivers/d3d12/d3d12_video_enc.cpp | 4 ++ .../drivers/d3d12/d3d12_video_screen.cpp | 52 ++++++++++++++++++- src/gallium/drivers/d3d12/d3d12_video_types.h | 2 + 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index a1a5cd3c5f5..41fc149a772 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -1737,6 +1737,10 @@ d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pi codec->entrypoint, PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL); + // Cache texture array requirement for reconstructed frames for d3d12_video_create_dpb_buffer calls + if (d3d12_video_encode_requires_texture_array_dpb(pD3D12Enc->m_pD3D12Screen, codec->profile)) + pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags |= D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS; + return &pD3D12Enc->base; failed: diff --git a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp index cc223d4e7ee..72d04583de7 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_screen.cpp @@ -856,7 +856,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, uint32_t &max_tile_rows, uint32_t &max_tile_cols, uint32_t &maxIRDuration, - union pipe_enc_cap_roi &roi_support) + union pipe_enc_cap_roi &roi_support, + bool &bVideoEncodeRequiresTextureArray) { ComPtr spD3D12VideoDevice; struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen; @@ -933,6 +934,7 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, capEncoderSupportData1, resolutionDepCaps, maxQualityLevels); + bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0; if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) maxSlices = 0; else @@ -1212,6 +1214,7 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, capEncoderSupportData1, resolutionDepCaps, maxQualityLevels); + bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0; if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) maxSlices = 0; else @@ -1473,6 +1476,7 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen, capEncoderSupportData1, resolutionDepCaps, maxQualityLevels); + bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0; if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE) maxSlices = 0; else @@ -1776,6 +1780,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen, enum pipe_video_entrypoint entrypoint, enum pipe_video_cap param) { + bool bVideoEncodeRequiresTextureArray = false; uint32_t maxLvlEncode = 0u; D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC minResEncode = {}; D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC maxResEncode = {}; @@ -1866,7 +1871,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen, max_tile_rows, max_tile_cols, maxIRDuration, - roi_support)) { + roi_support, + bVideoEncodeRequiresTextureArray)) { DXGI_FORMAT format = d3d12_convert_pipe_video_profile_to_dxgi_format(profile); auto pipeFmt = d3d12_get_pipe_format(format); @@ -1994,6 +2000,48 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen, } } +bool +d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum pipe_video_profile profile) +{ + bool bVideoEncodeRequiresTextureArray = false; + uint32_t maxLvlEncode = 0u; + D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC minResEncode = {}; + D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC maxResEncode = {}; + union pipe_enc_cap_surface_alignment alignResEncode = {}; + uint32_t maxSlices = 0u; + uint32_t supportedSliceStructures = 0u; + uint32_t maxReferencesPerFrame = 0u; + uint32_t isRCMaxFrameSizeSupported = 0u; + uint32_t maxQualityLevels = 0u; + uint32_t max_tile_rows = 0u; + uint32_t max_tile_cols = 0u; + uint32_t maxIRDuration = 0u; + union pipe_enc_cap_roi roi_support = {}; + struct d3d12_encode_codec_support codec_specific_support; + memset(&codec_specific_support, 0, sizeof(codec_specific_support)); + if (d3d12_has_video_encode_support(&pScreen->base, + profile, + maxLvlEncode, + minResEncode, + maxResEncode, + alignResEncode, + maxSlices, + supportedSliceStructures, + maxReferencesPerFrame, + codec_specific_support, + isRCMaxFrameSizeSupported, + maxQualityLevels, + max_tile_rows, + max_tile_cols, + maxIRDuration, + roi_support, + bVideoEncodeRequiresTextureArray)) + { + return bVideoEncodeRequiresTextureArray; + } + return false; +} + static int d3d12_screen_get_video_param(struct pipe_screen *pscreen, enum pipe_video_profile profile, diff --git a/src/gallium/drivers/d3d12/d3d12_video_types.h b/src/gallium/drivers/d3d12/d3d12_video_types.h index cbdfa1d5480..d908e8b8a7a 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_types.h +++ b/src/gallium/drivers/d3d12/d3d12_video_types.h @@ -162,6 +162,8 @@ D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT ConvertHEVCSupportFromProfile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile, D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC1* pSupport1); D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA ConvertHEVCPicParamsFromProfile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile, D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC1* pPictureParams1); +bool +d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum pipe_video_profile profile); DEFINE_ENUM_FLAG_OPERATORS(pipe_enc_feature); DEFINE_ENUM_FLAG_OPERATORS(pipe_h265_enc_pred_direction);