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 <benjamin.cheng@amd.com>
Reviewed-by: Benjamin Cheng <benjamin.cheng@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33824>
This commit is contained in:
Sil Vilerino
2025-02-28 14:13:31 -05:00
committed by Marge Bot
parent 7dd81ac9c2
commit 4a62f8bc75
3 changed files with 56 additions and 2 deletions
@@ -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:
@@ -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<ID3D12VideoDevice3> 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,
@@ -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);