mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 10:50:16 +01:00
d3d12: Implement PIPE_VIDEO_CAP_ENC_QP_MAPS and CPU/GPU input QPMaps
Reviewed-By: Pohsiang Hsu <pohhsu@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34844>
This commit is contained in:
parent
5810c39978
commit
2c193547ca
6 changed files with 276 additions and 35 deletions
|
|
@ -385,6 +385,68 @@ d3d12_video_encoder_update_move_rects(struct d3d12_video_encoder *pD3D12Enc,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
static void d3d12_video_encoder_is_gpu_qmap_input_feature_enabled(struct d3d12_video_encoder* pD3D12Enc, BOOL& isEnabled, D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE &outMapSourceEnabled)
|
||||
{
|
||||
isEnabled = FALSE;
|
||||
|
||||
//
|
||||
// Prefer GPU QP Map over CPU QP Delta Map if both are enabled
|
||||
//
|
||||
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested)
|
||||
{
|
||||
isEnabled = TRUE;
|
||||
outMapSourceEnabled = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
assert(!pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.AppRequested); // When enabling CPU QP Map, GPU QP Delta must be disabled
|
||||
}
|
||||
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.AppRequested)
|
||||
{
|
||||
isEnabled = TRUE;
|
||||
outMapSourceEnabled = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE;
|
||||
assert(!pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested); // When enabling GPU QP Map, CPU QP Delta must be disabled
|
||||
}
|
||||
}
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|
||||
void
|
||||
d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc,
|
||||
struct pipe_resource* qpmap,
|
||||
struct pipe_enc_roi roi,
|
||||
uint32_t temporal_id)
|
||||
{
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
//
|
||||
// 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;
|
||||
|
||||
//
|
||||
// Check if CPU/GPU QP Maps are enabled and store it in the context
|
||||
//
|
||||
if (qpmap)
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.AppRequested = true;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.InputMap = d3d12_resource(qpmap);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
}
|
||||
|
||||
if (roi.num > 0)
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested = true;
|
||||
// pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.* QP matrices are copied over in
|
||||
// d3d12_video_encoder_xxx.cpp by calling d3d12_video_encoder_update_picparams_region_of_interest_qpmap method
|
||||
// from the different ROI structures/ranges passed by the application
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_video_encoder_update_dirty_rects(struct d3d12_video_encoder *pD3D12Enc,
|
||||
const struct pipe_enc_dirty_info& rects)
|
||||
|
|
@ -1553,6 +1615,9 @@ bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3
|
|||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.MapValuesType :
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.MapValuesType;
|
||||
}
|
||||
|
||||
d3d12_video_encoder_is_gpu_qmap_input_feature_enabled(pD3D12Enc, /*output param*/ capEncoderSupportData1.QPMap.Enabled, /*output param*/ capEncoderSupportData1.QPMap.MapSource);
|
||||
|
||||
#endif
|
||||
|
||||
enum pipe_video_format codec = u_reduce_video_profile(pD3D12Enc->base.profile);
|
||||
|
|
@ -1711,6 +1776,45 @@ bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3
|
|||
}
|
||||
}
|
||||
|
||||
if ((capEncoderSupportData1.QPMap.MapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE) &&
|
||||
(capEncoderSupportData1.QPMap.Enabled))
|
||||
{
|
||||
// Query specifics of staging resource for QPMap regions
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap =
|
||||
{
|
||||
// UINT NodeIndex;
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SESSION_INFO SessionInfo;
|
||||
{
|
||||
capEncoderSupportData1.Codec,
|
||||
d3d12_video_encoder_get_current_profile_desc(pD3D12Enc),
|
||||
d3d12_video_encoder_get_current_level_desc(pD3D12Enc),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encodeFormatInfo.Format,
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC
|
||||
pD3D12Enc->m_currentEncodeConfig.m_currentResolution,
|
||||
d3d12_video_encoder_get_current_codec_config_desc(pD3D12Enc),
|
||||
capEncoderSupportData1.SubregionFrameEncoding,
|
||||
capEncoderSupportData1.SubregionFrameEncodingData
|
||||
},
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE MapType;
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE_QUANTIZATION_MATRIX,
|
||||
// BOOL IsSupported;
|
||||
FALSE,
|
||||
// UINT64 MaxResolvedBufferAllocationSize;
|
||||
0u,
|
||||
};
|
||||
|
||||
hr = pD3D12Enc->m_spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT,
|
||||
&pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap,
|
||||
sizeof(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
debug_printf("CheckFeatureSupport D3D12_FEATURE_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT failed with HR %x\n", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1834,6 +1938,9 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
|
||||
d3d12_video_encoder_update_move_rects(pD3D12Enc, ((struct pipe_h264_enc_picture_desc *)picture)->move_rects);
|
||||
d3d12_video_encoder_update_dirty_rects(pD3D12Enc, ((struct pipe_h264_enc_picture_desc *)picture)->dirty_info);
|
||||
d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_h264_enc_picture_desc *)picture)->input_gpu_qpmap,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->roi,
|
||||
((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;
|
||||
|
|
@ -1848,6 +1955,9 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
|
||||
d3d12_video_encoder_update_move_rects(pD3D12Enc, ((struct pipe_h265_enc_picture_desc *)picture)->move_rects);
|
||||
d3d12_video_encoder_update_dirty_rects(pD3D12Enc, ((struct pipe_h265_enc_picture_desc *)picture)->dirty_info);
|
||||
d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_h265_enc_picture_desc *)picture)->input_gpu_qpmap,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->roi,
|
||||
((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;
|
||||
|
|
@ -1855,6 +1965,10 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
#if VIDEO_CODEC_AV1ENC
|
||||
case PIPE_VIDEO_FORMAT_AV1:
|
||||
{
|
||||
d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_av1_enc_picture_desc *)picture)->input_gpu_qpmap,
|
||||
((struct pipe_av1_enc_picture_desc *)picture)->roi,
|
||||
((struct pipe_av1_enc_picture_desc *)picture)->temporal_id);
|
||||
// ...encoder_config_state_av1 calls encoder support cap, set any state before this call
|
||||
bCodecUpdatesSuccess = d3d12_video_encoder_update_current_encoder_config_state_av1(pD3D12Enc, srcTextureDesc, picture);
|
||||
} break;
|
||||
#endif
|
||||
|
|
@ -2150,6 +2264,31 @@ d3d12_video_encoder_prepare_input_buffers(struct d3d12_video_encoder *pD3D12Enc)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL QPMapEnabled = FALSE;
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE QPMapSource = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
d3d12_video_encoder_is_gpu_qmap_input_feature_enabled(pD3D12Enc, /*output param*/ QPMapEnabled, /*output param*/ QPMapSource);
|
||||
if (QPMapEnabled && (QPMapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE))
|
||||
{
|
||||
bool bNeedsCreation = (pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spQPMapResolvedOpaqueMap == NULL) ||
|
||||
(GetDesc(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spQPMapResolvedOpaqueMap.Get()).Width <
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap.MaxResolvedBufferAllocationSize);
|
||||
if (bNeedsCreation)
|
||||
{
|
||||
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spQPMapResolvedOpaqueMap.Reset();
|
||||
CD3DX12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap.MaxResolvedBufferAllocationSize);
|
||||
hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommittedResource(&Properties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spQPMapResolvedOpaqueMap));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
debug_printf("CreateCommittedResource for m_spQPMapResolvedOpaqueMap failed with HR %x\n", hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
|
@ -2951,6 +3090,47 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
D3D12_VIDEO_ENCODER_QUANTIZATION_OPAQUE_MAP QuantizationTextureMap = {};
|
||||
BOOL QPMapEnabled = false;
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE QPMapSource = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
d3d12_video_encoder_is_gpu_qmap_input_feature_enabled(pD3D12Enc, /*output param*/ QPMapEnabled, /*output param*/ QPMapSource);
|
||||
if (QPMapEnabled && (QPMapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE))
|
||||
{
|
||||
picCtrlFlags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_ENABLE_QUANTIZATION_MATRIX_INPUT;
|
||||
QuantizationTextureMap.pOpaqueQuantizationMap = pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spQPMapResolvedOpaqueMap.Get();
|
||||
|
||||
pResolveInputDataBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(QuantizationTextureMap.pOpaqueQuantizationMap,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE));
|
||||
|
||||
pResolveInputDataBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.InputMap),
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ));
|
||||
|
||||
// see below std::warp for reversal to common after ResolveInputParamLayout is done
|
||||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(static_cast<uint32_t>(pResolveInputDataBarriers.size()),
|
||||
pResolveInputDataBarriers.data());
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_DATA ResolveInputData = {};
|
||||
ResolveInputData.MapType = D3D12_VIDEO_ENCODER_INPUT_MAP_TYPE_QUANTIZATION_MATRIX;
|
||||
ResolveInputData.Quantization.pQuantizationMap = d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.InputMap);
|
||||
D3D12_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT_INPUT_ARGUMENTS resolveInputParamLayoutInput =
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.capInputLayoutQPMap.SessionInfo,
|
||||
ResolveInputData,
|
||||
};
|
||||
D3D12_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT_OUTPUT_ARGUMENTS resolveInputParamLayoutOutput =
|
||||
{
|
||||
QuantizationTextureMap.pOpaqueQuantizationMap,
|
||||
};
|
||||
|
||||
pD3D12Enc->m_spEncodeCommandList->ResolveInputParamLayout(&resolveInputParamLayoutInput, &resolveInputParamLayoutOutput);
|
||||
for (auto &BarrierDesc : pResolveInputDataBarriers) {
|
||||
std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter);
|
||||
}
|
||||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(static_cast<uint32_t>(pResolveInputDataBarriers.size()),
|
||||
pResolveInputDataBarriers.data());
|
||||
}
|
||||
|
||||
D3D12_VIDEO_ENCODER_FRAME_MOTION_VECTORS motionRegions = { };
|
||||
motionRegions.MapSource = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
motionRegions.pCPUBuffer = &pD3D12Enc->m_currentEncodeConfig.m_MoveRectsDesc;
|
||||
|
|
@ -3026,7 +3206,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
|||
// D3D12_VIDEO_ENCODER_DIRTY_REGIONS DirtyRects;
|
||||
dirtyRegions,
|
||||
// D3D12_VIDEO_ENCODER_QUANTIZATION_OPAQUE_MAP QuantizationTextureMap;
|
||||
{},
|
||||
QuantizationTextureMap,
|
||||
#endif
|
||||
},
|
||||
pInputVideoD3D12Res,
|
||||
|
|
|
|||
|
|
@ -232,10 +232,6 @@ struct D3D12EncodeRateControlState
|
|||
D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR1 m_Configuration_VBR1;
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR1 m_Configuration_QVBR1;
|
||||
} m_Config;
|
||||
|
||||
// AV1 uses 16 bit integers, H26x uses 8 bit integers
|
||||
std::vector<int8_t> m_pRateControlQPMap8Bit;
|
||||
std::vector<int16_t> m_pRateControlQPMap16Bit;
|
||||
};
|
||||
|
||||
struct D3D12EncodeConfiguration
|
||||
|
|
@ -339,6 +335,20 @@ struct D3D12EncodeConfiguration
|
|||
} MapInfo;
|
||||
};
|
||||
} m_DirtyRectsDesc = {};
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
bool AppRequested;
|
||||
struct d3d12_resource* InputMap;
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT capInputLayoutQPMap;
|
||||
} GPUInput;
|
||||
struct {
|
||||
bool AppRequested;
|
||||
// AV1 uses 16 bit integers, H26x uses 8 bit integers
|
||||
std::vector<int8_t> m_pRateControlQPMap8Bit;
|
||||
std::vector<int16_t> m_pRateControlQPMap16Bit;
|
||||
} CPUInput;
|
||||
} m_QuantizationMatrixDesc = {};
|
||||
std::vector<RECT> m_DirtyRectsArray;
|
||||
D3D12_VIDEO_ENCODER_MOVEREGION_INFO m_MoveRectsDesc = {};
|
||||
std::vector<D3D12_VIDEO_ENCODER_MOVE_RECT> m_MoveRectsArray;
|
||||
|
|
@ -522,6 +532,7 @@ struct d3d12_video_encoder
|
|||
enum pipe_video_feedback_encode_result_flags encode_result = PIPE_VIDEO_FEEDBACK_METADATA_ENCODE_FLAG_OK;
|
||||
|
||||
ComPtr<ID3D12Resource> m_spDirtyRectsResolvedOpaqueMap; // output of ID3D12VideoEncodeCommandList::ResolveInputParamLayout
|
||||
ComPtr<ID3D12Resource> m_spQPMapResolvedOpaqueMap; // output of ID3D12VideoEncodeCommandList::ResolveInputParamLayout
|
||||
};
|
||||
|
||||
std::vector<InFlightEncodeResources> m_inflightResourcesPool;
|
||||
|
|
@ -662,6 +673,12 @@ d3d12_video_encoder_update_output_stats_resources(struct d3d12_video_encoder *pD
|
|||
|
||||
bool
|
||||
d3d12_video_encoder_prepare_input_buffers(struct d3d12_video_encoder *pD3D12Enc);
|
||||
|
||||
void
|
||||
d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc,
|
||||
struct pipe_resource* qpmap,
|
||||
struct pipe_enc_roi roi,
|
||||
uint32_t temporal_id);
|
||||
///
|
||||
/// d3d12_video_encoder functions ends
|
||||
///
|
||||
|
|
|
|||
|
|
@ -39,14 +39,13 @@ d3d12_video_encoder_update_current_rate_control_av1(struct d3d12_video_encoder *
|
|||
|
||||
struct D3D12EncodeRateControlState m_prevRCState = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id];
|
||||
pD3D12Enc->m_currentEncodeConfig.m_activeRateControlIndex = picture->temporal_id;
|
||||
bool wasDeltaQPRequested = (pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id] = {};
|
||||
if (wasDeltaQPRequested)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_FrameRate.Numerator = picture->rc[picture->temporal_id].frame_rate_num;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_FrameRate.Denominator = picture->rc[picture->temporal_id].frame_rate_den;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
|
||||
|
||||
if (picture->roi.num > 0)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
switch (picture->rc[picture->temporal_id].rate_ctrl_method) {
|
||||
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
|
||||
|
|
@ -1631,7 +1630,8 @@ d3d12_video_encoder_update_current_frame_pic_params_info_av1(struct d3d12_video_
|
|||
// pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot]
|
||||
// .m_CodecSpecificData.AV1HeadersInfo.temporal_delim_rendered = pAV1Pic->temporal_delim_rendered;
|
||||
|
||||
if ((pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[pAV1Pic->temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0)
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested)
|
||||
{
|
||||
// Use 16 bit qpmap array for AV1 picparams (-255, 255 range and int16_t pRateControlQPMap type)
|
||||
const int32_t av1_min_delta_qp = -255;
|
||||
|
|
@ -1641,10 +1641,11 @@ d3d12_video_encoder_update_current_frame_pic_params_info_av1(struct d3d12_video_
|
|||
&pAV1Pic->roi,
|
||||
av1_min_delta_qp,
|
||||
av1_max_delta_qp,
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[pAV1Pic->temporal_id].m_pRateControlQPMap16Bit);
|
||||
picParams.pAV1PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[pAV1Pic->temporal_id].m_pRateControlQPMap16Bit.data();
|
||||
picParams.pAV1PicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[pAV1Pic->temporal_id].m_pRateControlQPMap16Bit.size());
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit);
|
||||
picParams.pAV1PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit.data();
|
||||
picParams.pAV1PicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit.size());
|
||||
}
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -43,16 +43,14 @@ d3d12_video_encoder_update_current_rate_control_h264(struct d3d12_video_encoder
|
|||
|
||||
struct D3D12EncodeRateControlState m_prevRCState = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic_ctrl.temporal_id];
|
||||
pD3D12Enc->m_currentEncodeConfig.m_activeRateControlIndex = h264Pic->pic_ctrl.temporal_id;
|
||||
bool wasDeltaQPRequested = (pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id] = {};
|
||||
if (wasDeltaQPRequested)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_FrameRate.Numerator =
|
||||
picture->rate_ctrl[h264Pic->pic_ctrl.temporal_id].frame_rate_num;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_FrameRate.Denominator =
|
||||
picture->rate_ctrl[h264Pic->pic_ctrl.temporal_id].frame_rate_den;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
|
||||
|
||||
if (picture->roi.num > 0)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
switch (picture->rate_ctrl[h264Pic->pic_ctrl.temporal_id].rate_ctrl_method) {
|
||||
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
|
||||
|
|
@ -379,7 +377,8 @@ d3d12_video_encoder_update_current_frame_pic_params_info_h264(struct d3d12_video
|
|||
if (h264Pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B)
|
||||
picParams.pH264PicData->List1ReferenceFramesCount = h264Pic->num_ref_idx_l1_active_minus1 + 1;
|
||||
|
||||
if ((pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0)
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested)
|
||||
{
|
||||
// Use 8 bit qpmap array for H264 picparams (-51, 51 range and int8_t pRateControlQPMap type)
|
||||
const int32_t h264_min_delta_qp = -51;
|
||||
|
|
@ -389,10 +388,11 @@ d3d12_video_encoder_update_current_frame_pic_params_info_h264(struct d3d12_video
|
|||
&h264Pic->roi,
|
||||
h264_min_delta_qp,
|
||||
h264_max_delta_qp,
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_pRateControlQPMap8Bit);
|
||||
picParams.pH264PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_pRateControlQPMap8Bit.data();
|
||||
picParams.pH264PicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[h264Pic->pic_ctrl.temporal_id].m_pRateControlQPMap8Bit.size());
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit);
|
||||
picParams.pH264PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.data();
|
||||
picParams.pH264PicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.size());
|
||||
}
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|
||||
pD3D12Enc->m_upDPBManager->begin_frame(picParams, bUsedAsReference, picture);
|
||||
pD3D12Enc->m_upDPBManager->get_current_frame_picture_control_data(picParams);
|
||||
|
|
|
|||
|
|
@ -41,16 +41,15 @@ d3d12_video_encoder_update_current_rate_control_hevc(struct d3d12_video_encoder
|
|||
|
||||
struct D3D12EncodeRateControlState m_prevRCState = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id];
|
||||
pD3D12Enc->m_currentEncodeConfig.m_activeRateControlIndex = picture->pic.temporal_id;
|
||||
bool wasDeltaQPRequested = (pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id] = {};
|
||||
if (wasDeltaQPRequested)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_FrameRate.Numerator =
|
||||
picture->rc[picture->pic.temporal_id].frame_rate_num;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_FrameRate.Denominator =
|
||||
picture->rc[picture->pic.temporal_id].frame_rate_den;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_Flags = D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_NONE;
|
||||
|
||||
if (picture->roi.num > 0)
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[picture->pic.temporal_id].m_Flags |=
|
||||
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP;
|
||||
|
||||
switch (picture->rc[picture->pic.temporal_id].rate_ctrl_method) {
|
||||
case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
|
||||
|
|
@ -545,7 +544,7 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video
|
|||
& D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ALLOW_REQUEST_INTRA_CONSTRAINED_SLICES) != 0)
|
||||
picParams.pHEVCPicData->Flags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC_FLAG_REQUEST_INTRA_CONSTRAINED_SLICES;
|
||||
|
||||
if ((pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[hevcPic->pic.temporal_id].m_Flags & D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP) != 0)
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.AppRequested)
|
||||
{
|
||||
// Use 8 bit qpmap array for HEVC picparams (-51, 51 range and int8_t pRateControlQPMap type)
|
||||
const int32_t hevc_min_delta_qp = -51;
|
||||
|
|
@ -555,9 +554,9 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video
|
|||
&hevcPic->roi,
|
||||
hevc_min_delta_qp,
|
||||
hevc_max_delta_qp,
|
||||
pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[hevcPic->pic.temporal_id].m_pRateControlQPMap8Bit);
|
||||
picParams.pHEVCPicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[hevcPic->pic.temporal_id].m_pRateControlQPMap8Bit.data();
|
||||
picParams.pHEVCPicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[hevcPic->pic.temporal_id].m_pRateControlQPMap8Bit.size());
|
||||
pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit);
|
||||
picParams.pHEVCPicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.data();
|
||||
picParams.pHEVCPicData->QPMapValuesCount = static_cast<UINT>(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.size());
|
||||
}
|
||||
|
||||
pD3D12Enc->m_upDPBManager->begin_frame(picParams, bUsedAsReference, picture);
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,41 @@ get_sliced_encode_support(D3D12_VIDEO_ENCODER_SUPPORT_FLAGS capEncoderSupportFla
|
|||
return sliced_encode_support;
|
||||
}
|
||||
|
||||
static
|
||||
union pipe_enc_cap_qpmap
|
||||
get_qpmap_gpuinput_support(D3D12_VIDEO_ENCODER_INPUT_MAP_SESSION_INFO sessionInfo,
|
||||
ID3D12VideoDevice3* pD3D12VideoDevice)
|
||||
{
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_QPMAP_INPUT capQPInput =
|
||||
{
|
||||
// UINT NodeIndex;
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SESSION_INFO SessionInfo;
|
||||
sessionInfo,
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE MapSource;
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE,
|
||||
// BOOL IsSupported;
|
||||
FALSE,
|
||||
// UINT MapSourcePreferenceRanking;
|
||||
0u,
|
||||
// UINT BlockSize;
|
||||
0u,
|
||||
};
|
||||
|
||||
union pipe_enc_cap_qpmap qpmap_gpu_support = {};
|
||||
if (SUCCEEDED(pD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_QPMAP_INPUT, &capQPInput, sizeof(capQPInput))))
|
||||
{
|
||||
qpmap_gpu_support.bits.supported = capQPInput.IsSupported ? 1u : 0u;
|
||||
if (qpmap_gpu_support.bits.supported)
|
||||
{
|
||||
qpmap_gpu_support.bits.pipe_pixel_format = PIPE_FORMAT_R8_UINT; // As per DX12 spec
|
||||
qpmap_gpu_support.bits.log2_values_block_size = static_cast<uint32_t>(std::log2(capQPInput.BlockSize));
|
||||
}
|
||||
}
|
||||
|
||||
return qpmap_gpu_support;
|
||||
}
|
||||
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|
||||
static bool
|
||||
|
|
@ -1090,7 +1125,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_gpu_stats_map &gpu_stats_satd,
|
||||
union pipe_enc_cap_gpu_stats_map &gpu_stats_rcbits,
|
||||
union pipe_enc_cap_sliced_notifications &sliced_encode_support,
|
||||
union pipe_enc_cap_dirty_info &dirty_rects_support_gpu)
|
||||
union pipe_enc_cap_dirty_info &dirty_rects_support_gpu,
|
||||
union pipe_enc_cap_qpmap &qpmap_support)
|
||||
{
|
||||
ComPtr<ID3D12VideoDevice3> spD3D12VideoDevice;
|
||||
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
|
||||
|
|
@ -1224,6 +1260,7 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
move_rects_support = get_move_rects_support(sessionInfo, spD3D12VideoDevice.Get());
|
||||
get_gpu_output_stats_support(sessionInfo, capEncoderSupportData1.SupportFlags, spD3D12VideoDevice.Get(), gpu_stats_qp, gpu_stats_satd, gpu_stats_rcbits);
|
||||
sliced_encode_support = get_sliced_encode_support(capEncoderSupportData1.SupportFlags);
|
||||
qpmap_support = get_qpmap_gpuinput_support(sessionInfo, spD3D12VideoDevice.Get());
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
|
|
@ -2119,6 +2156,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_gpu_stats_map gpu_stats_satd = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_rcbits = {};
|
||||
union pipe_enc_cap_sliced_notifications sliced_encode_support = {};
|
||||
union pipe_enc_cap_qpmap gpu_qpmap_input = {};
|
||||
memset(&codec_specific_support, 0, sizeof(codec_specific_support));
|
||||
switch (param) {
|
||||
case PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME:
|
||||
|
|
@ -2188,6 +2226,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_RATE_CONTROL_BITS_MAP:
|
||||
case PIPE_VIDEO_CAP_ENC_SLICED_NOTIFICATIONS:
|
||||
case PIPE_VIDEO_CAP_ENC_DIRTY_MAPS:
|
||||
case PIPE_VIDEO_CAP_ENC_QP_MAPS:
|
||||
{
|
||||
if (d3d12_has_video_encode_support(pscreen,
|
||||
profile,
|
||||
|
|
@ -2214,7 +2253,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
gpu_stats_satd,
|
||||
gpu_stats_rcbits,
|
||||
sliced_encode_support,
|
||||
dirty_rects_support_gpu)) {
|
||||
dirty_rects_support_gpu,
|
||||
gpu_qpmap_input)) {
|
||||
|
||||
DXGI_FORMAT format = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
|
||||
auto pipeFmt = d3d12_get_pipe_format(format);
|
||||
|
|
@ -2313,6 +2353,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
return sliced_encode_support.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_DIRTY_MAPS) {
|
||||
return dirty_rects_support_gpu.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_QP_MAPS) {
|
||||
return gpu_qpmap_input.value;
|
||||
}
|
||||
}
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL) {
|
||||
|
|
@ -2388,6 +2430,7 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
union pipe_enc_cap_gpu_stats_map gpu_stats_satd = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_rcbits = {};
|
||||
union pipe_enc_cap_sliced_notifications sliced_encode_support = {};
|
||||
union pipe_enc_cap_qpmap gpu_qpmap_input = {};
|
||||
if (d3d12_has_video_encode_support(&pScreen->base,
|
||||
profile,
|
||||
maxLvlEncode,
|
||||
|
|
@ -2413,7 +2456,8 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
gpu_stats_satd,
|
||||
gpu_stats_rcbits,
|
||||
sliced_encode_support,
|
||||
dirty_rects_support_gpu))
|
||||
dirty_rects_support_gpu,
|
||||
gpu_qpmap_input))
|
||||
{
|
||||
return bVideoEncodeRequiresTextureArray;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue