mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 02:10:12 +01:00
d3d12: Implement video encode spatial adaptive quantization interface
Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37581>
This commit is contained in:
parent
ce7c4e14ef
commit
0e73c6470e
2 changed files with 50 additions and 8 deletions
|
|
@ -424,7 +424,7 @@ d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc,
|
|||
// Clear QPDelta context for this frame
|
||||
//
|
||||
memset(&pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc, 0, sizeof(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc));
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags &= ~D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
//
|
||||
// Check if CPU/GPU QP Maps are enabled and store it in the context
|
||||
|
|
@ -478,6 +478,23 @@ d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc,
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_video_encoder_update_rate_control_saq(struct d3d12_video_encoder *pD3D12Enc,
|
||||
uint32_t saq_strength,
|
||||
uint32_t temporal_id)
|
||||
{
|
||||
//
|
||||
// Clear SAQ flag for this frame and only enable it below if saq_strength > 0
|
||||
//
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags &= ~D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_SPATIAL_ADAPTIVE_QP;
|
||||
|
||||
if (saq_strength > 0)
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_SPATIAL_ADAPTIVE_QP;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called on encoder creation with the encoder creation parameters
|
||||
*/
|
||||
|
|
@ -2310,6 +2327,9 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
((struct pipe_h264_enc_picture_desc *)picture)->roi,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->pic_ctrl.temporal_id);
|
||||
d3d12_video_encoder_update_two_pass_frame_settings(pD3D12Enc, codec, picture);
|
||||
d3d12_video_encoder_update_rate_control_saq(pD3D12Enc,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->rate_ctrl[((struct pipe_h264_enc_picture_desc *)picture)->pic_ctrl.temporal_id].spatial_adaptive_quantization_strength,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->pic_ctrl.temporal_id);
|
||||
// ...encoder_config_state_h264 calls encoder support cap, set any state before this call
|
||||
bCodecUpdatesSuccess = d3d12_video_encoder_update_current_encoder_config_state_h264(pD3D12Enc, srcTextureDesc, picture);
|
||||
} break;
|
||||
|
|
@ -2329,6 +2349,9 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
((struct pipe_h265_enc_picture_desc *)picture)->roi,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->pic.temporal_id);
|
||||
d3d12_video_encoder_update_two_pass_frame_settings(pD3D12Enc, codec, picture);
|
||||
d3d12_video_encoder_update_rate_control_saq(pD3D12Enc,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->rc[((struct pipe_h265_enc_picture_desc *)picture)->pic.temporal_id].spatial_adaptive_quantization_strength,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->pic.temporal_id);
|
||||
// ...encoder_config_state_hevc calls encoder support cap, set any state before this call
|
||||
bCodecUpdatesSuccess = d3d12_video_encoder_update_current_encoder_config_state_hevc(pD3D12Enc, srcTextureDesc, picture);
|
||||
} break;
|
||||
|
|
|
|||
|
|
@ -627,7 +627,8 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec,
|
|||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS &resolutionDepCaps,
|
||||
#endif
|
||||
uint32_t &maxQualityLevels,
|
||||
struct d3d12_encode_support_cap_allocations &cap_allocations)
|
||||
struct d3d12_encode_support_cap_allocations &cap_allocations,
|
||||
union pipe_enc_cap_spatial_adaptive_quantization &saqSupport)
|
||||
{
|
||||
capEncoderSupportData1.NodeIndex = 0;
|
||||
capEncoderSupportData1.Codec = argTargetCodec;
|
||||
|
|
@ -772,6 +773,13 @@ d3d12_video_encode_support_caps(const D3D12_VIDEO_ENCODER_CODEC &argTargetCodec,
|
|||
// consumption, with higher quality corresponds to lower speed and higher power consumption.
|
||||
maxQualityLevels = capEncoderSupportData1.MaxQualityVsSpeed + 1; // VA range starts from 1, D3D12 starts from 0
|
||||
|
||||
saqSupport.bits.max_spatial_adaptive_quantization_strength = 0u;
|
||||
|
||||
if ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_SPATIAL_ADAPTIVE_QP_AVAILABLE) != 0)
|
||||
{
|
||||
saqSupport.bits.max_spatial_adaptive_quantization_strength = 1u;
|
||||
}
|
||||
|
||||
bool configSupported =
|
||||
(((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_GENERAL_SUPPORT_OK) != 0) &&
|
||||
(capEncoderSupportData1.ValidationFlags == D3D12_VIDEO_ENCODER_VALIDATION_FLAG_NONE));
|
||||
|
|
@ -1491,7 +1499,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_qpmap &qpmap_support,
|
||||
union pipe_enc_cap_motion_vector_map &gpu_motion_input_support,
|
||||
union pipe_enc_cap_two_pass &two_pass_support,
|
||||
union pipe_enc_cap_gpu_stats_psnr& psnr_support)
|
||||
union pipe_enc_cap_gpu_stats_psnr& psnr_support,
|
||||
union pipe_enc_cap_spatial_adaptive_quantization &saqSupport)
|
||||
{
|
||||
ComPtr<ID3D12VideoDevice3> spD3D12VideoDevice;
|
||||
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
|
||||
|
|
@ -1574,7 +1583,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
capEncoderSupportData1,
|
||||
resolutionDepCaps,
|
||||
maxQualityLevels,
|
||||
cap_allocations);
|
||||
cap_allocations,
|
||||
saqSupport);
|
||||
bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0;
|
||||
if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE)
|
||||
maxSlices = 0;
|
||||
|
|
@ -1915,7 +1925,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
capEncoderSupportData1,
|
||||
resolutionDepCaps,
|
||||
maxQualityLevels,
|
||||
cap_allocations);
|
||||
cap_allocations,
|
||||
saqSupport);
|
||||
bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0;
|
||||
if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE)
|
||||
maxSlices = 0;
|
||||
|
|
@ -2219,7 +2230,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
capEncoderSupportData1,
|
||||
resolutionDepCaps,
|
||||
maxQualityLevels,
|
||||
cap_allocations);
|
||||
cap_allocations,
|
||||
saqSupport);
|
||||
bVideoEncodeRequiresTextureArray = (capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) != 0;
|
||||
if (supportedSliceStructures == PIPE_VIDEO_CAP_SLICE_STRUCTURE_NONE)
|
||||
maxSlices = 0;
|
||||
|
|
@ -2474,6 +2486,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_two_pass two_pass_support = {};
|
||||
union pipe_enc_cap_gpu_stats_psnr psnr_support = {};
|
||||
memset(&codec_specific_support, 0, sizeof(codec_specific_support));
|
||||
union pipe_enc_cap_spatial_adaptive_quantization saqSupport = {};
|
||||
switch (param) {
|
||||
case PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME:
|
||||
return 1;
|
||||
|
|
@ -2546,6 +2559,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
case PIPE_VIDEO_CAP_ENC_MOTION_VECTOR_MAPS:
|
||||
case PIPE_VIDEO_CAP_ENC_TWO_PASS:
|
||||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_PSNR:
|
||||
case PIPE_VIDEO_CAP_ENC_SPATIAL_ADAPTIVE_QUANTIZATION:
|
||||
{
|
||||
if (d3d12_has_video_encode_support(pscreen,
|
||||
profile,
|
||||
|
|
@ -2576,7 +2590,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
gpu_qpmap_input,
|
||||
gpu_motion_input,
|
||||
two_pass_support,
|
||||
psnr_support)) {
|
||||
psnr_support,
|
||||
saqSupport)) {
|
||||
|
||||
DXGI_FORMAT format = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
|
||||
auto pipeFmt = d3d12_get_pipe_format(format);
|
||||
|
|
@ -2685,6 +2700,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
return two_pass_support.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_GPU_STATS_PSNR ) {
|
||||
return psnr_support.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_SPATIAL_ADAPTIVE_QUANTIZATION ) {
|
||||
return saqSupport.value;
|
||||
}
|
||||
}
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL) {
|
||||
|
|
@ -2760,6 +2777,7 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
union pipe_enc_cap_motion_vector_map gpu_motion_input = {};
|
||||
union pipe_enc_cap_two_pass two_pass_support = {};
|
||||
union pipe_enc_cap_gpu_stats_psnr psnr_support = {};
|
||||
union pipe_enc_cap_spatial_adaptive_quantization saqSupport = {};
|
||||
if (d3d12_has_video_encode_support(&pScreen->base,
|
||||
profile,
|
||||
maxLvlEncode,
|
||||
|
|
@ -2789,7 +2807,8 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
gpu_qpmap_input,
|
||||
gpu_motion_input,
|
||||
two_pass_support,
|
||||
psnr_support))
|
||||
psnr_support,
|
||||
saqSupport))
|
||||
{
|
||||
return bVideoEncodeRequiresTextureArray;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue