mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
d3d12: Add support for QP, SATD and RC bits output stats
Reviewed-By: Pohsiang Hsu <pohhsu@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34844>
This commit is contained in:
parent
25726509ff
commit
c5f5ee41c8
3 changed files with 310 additions and 9 deletions
|
|
@ -1695,6 +1695,19 @@ d3d12_video_encoder_get_current_max_dpb_capacity(struct d3d12_video_encoder *pD3
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_video_encoder_update_output_stats_resources(struct d3d12_video_encoder *pD3D12Enc,
|
||||
struct pipe_resource* qpmap,
|
||||
struct pipe_resource* satdmap,
|
||||
struct pipe_resource* rcbitsmap)
|
||||
{
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource = d3d12_resource(qpmap);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource = d3d12_resource(satdmap);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource = d3d12_resource(rcbitsmap);
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
}
|
||||
|
||||
bool
|
||||
d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encoder *pD3D12Enc,
|
||||
D3D12_VIDEO_SAMPLE srcTextureDesc,
|
||||
|
|
@ -1708,6 +1721,11 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
#if VIDEO_CODEC_H264ENC
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
{
|
||||
d3d12_video_encoder_update_output_stats_resources(pD3D12Enc,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->gpu_stats_qp_map,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->gpu_stats_satd_map,
|
||||
((struct pipe_h264_enc_picture_desc *)picture)->gpu_stats_rc_bitallocation_map);
|
||||
|
||||
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_rects);
|
||||
// ...encoder_config_state_h264 calls encoder support cap, set any state before this call
|
||||
|
|
@ -1717,6 +1735,11 @@ d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encod
|
|||
#if VIDEO_CODEC_H265ENC
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
{
|
||||
d3d12_video_encoder_update_output_stats_resources(pD3D12Enc,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->gpu_stats_qp_map,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->gpu_stats_satd_map,
|
||||
((struct pipe_h265_enc_picture_desc *)picture)->gpu_stats_rc_bitallocation_map);
|
||||
|
||||
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_rects);
|
||||
// ...encoder_config_state_hevc calls encoder support cap, set any state before this call
|
||||
|
|
@ -1919,10 +1942,35 @@ d3d12_video_encoder_prepare_output_buffers(struct d3d12_video_encoder *pD3D12Enc
|
|||
pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps.PictureTargetResolution =
|
||||
pD3D12Enc->m_currentEncodeConfig.m_currentResolution;
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
// Assume all stats will be required and use max allocation to avoid reallocating between frames
|
||||
pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps.OptionalMetadata = D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_QP_MAP |
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_SATD_MAP |
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_RC_BIT_ALLOCATION_MAP;
|
||||
pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps.CodecConfiguration = d3d12_video_encoder_get_current_codec_config_desc(pD3D12Enc);
|
||||
|
||||
HRESULT hr = pD3D12Enc->m_spD3D12VideoDevice->CheckFeatureSupport(
|
||||
D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1,
|
||||
&pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps,
|
||||
sizeof(pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
debug_printf("CheckFeatureSupport D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1 failed with HR %x\n", hr);
|
||||
debug_printf("Falling back to check previous query version D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS...\n");
|
||||
|
||||
// D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1 extends D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS
|
||||
// in a binary compatible way, so just cast it and try with the older query D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS* casted_down_cap_data = reinterpret_cast<D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS*>(&pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps);
|
||||
hr = pD3D12Enc->m_spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS,
|
||||
casted_down_cap_data,
|
||||
sizeof(*casted_down_cap_data));
|
||||
}
|
||||
#else
|
||||
HRESULT hr = pD3D12Enc->m_spD3D12VideoDevice->CheckFeatureSupport(
|
||||
D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS,
|
||||
&pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps,
|
||||
sizeof(pD3D12Enc->m_currentEncodeCapabilities.m_ResourceRequirementsCaps));
|
||||
#endif
|
||||
|
||||
if (FAILED(hr)) {
|
||||
debug_printf("CheckFeatureSupport failed with HR %x\n", hr);
|
||||
|
|
@ -2467,6 +2515,43 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
if (motionRegions.pCPUBuffer->NumMoveRegions > 0)
|
||||
picCtrlFlags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_ENABLE_MOTION_VECTORS_INPUT;
|
||||
|
||||
ID3D12Resource* d12_gpu_stats_qp_map = NULL;
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS optionalMetadataFlags = D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_QP_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS);
|
||||
d3d12_resource_wait_idle(d3d12_context(pD3D12Enc->base.context), pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource, true /*wantToWrite*/);
|
||||
d12_gpu_stats_qp_map = d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource);
|
||||
}
|
||||
|
||||
ID3D12Resource* d12_gpu_stats_satd_map = NULL;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_SATD_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS);
|
||||
d3d12_resource_wait_idle(d3d12_context(pD3D12Enc->base.context), pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource, true /*wantToWrite*/);
|
||||
d12_gpu_stats_satd_map = d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource);
|
||||
}
|
||||
|
||||
ID3D12Resource* d12_gpu_stats_rc_bitallocation_map = NULL;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_RC_BIT_ALLOCATION_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_TRANSITION_FLAG_INVALIDATE_BINDINGS);
|
||||
d3d12_resource_wait_idle(d3d12_context(pD3D12Enc->base.context), pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource, true /*wantToWrite*/);
|
||||
d12_gpu_stats_rc_bitallocation_map = d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource);
|
||||
}
|
||||
|
||||
const D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS1 inputStreamArguments = {
|
||||
#else
|
||||
const D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS inputStreamArguments = {
|
||||
|
|
@ -2511,7 +2596,7 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
// ... extra params to initialize D3D12_VIDEO_ENCODER_ENCODEFRAME_INPUT_ARGUMENTS1
|
||||
, // extra comma from last param above #if
|
||||
// D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS OptionalMetadata;
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE, // must match with ResolveEncodeOutputMetadata flags
|
||||
optionalMetadataFlags, // must match with ResolveEncodeOutputMetadata flags
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -2588,6 +2673,31 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(_countof(rgResolveMetadataStateTransitions),
|
||||
rgResolveMetadataStateTransitions);
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|
||||
std::vector<D3D12_RESOURCE_BARRIER> output_stats_barriers;
|
||||
if (d12_gpu_stats_qp_map) {
|
||||
output_stats_barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(d12_gpu_stats_qp_map,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE));
|
||||
}
|
||||
|
||||
if (d12_gpu_stats_satd_map) {
|
||||
output_stats_barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(d12_gpu_stats_satd_map,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE));
|
||||
}
|
||||
|
||||
if (d12_gpu_stats_rc_bitallocation_map) {
|
||||
output_stats_barriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(d12_gpu_stats_rc_bitallocation_map,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE));
|
||||
}
|
||||
|
||||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(static_cast<uint32_t>(output_stats_barriers.size()),
|
||||
output_stats_barriers.data());
|
||||
#endif
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
const D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS1 inputMetadataCmd = {
|
||||
#else
|
||||
|
|
@ -2603,7 +2713,7 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
// ... extra params to initialize D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS1
|
||||
, // extra comma from last param above #if
|
||||
// D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS OptionalMetadata;
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE, // must match with EncodeFrame flags
|
||||
optionalMetadataFlags, // must match with EncodeFrame flags
|
||||
// D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION CodecConfiguration;
|
||||
d3d12_video_encoder_get_current_codec_config_desc(pD3D12Enc),
|
||||
#endif
|
||||
|
|
@ -2620,11 +2730,11 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
// ... extra params to initialize D3D12_VIDEO_ENCODER_RESOLVE_METADATA_OUTPUT_ARGUMENTS
|
||||
, // extra comma from last param above #if
|
||||
// ID3D12Resource *pOutputQPMap;
|
||||
NULL,
|
||||
d12_gpu_stats_qp_map,
|
||||
// ID3D12Resource *pOutputSATDMap;
|
||||
NULL,
|
||||
d12_gpu_stats_satd_map,
|
||||
// ID3D12Resource *pOutputBitAllocationMap;
|
||||
NULL,
|
||||
d12_gpu_stats_rc_bitallocation_map,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -2673,6 +2783,16 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec,
|
|||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions),
|
||||
rgRevertResolveMetadataStateTransitions);
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
// Revert output_stats_barriers
|
||||
for (auto &BarrierDesc : output_stats_barriers) {
|
||||
std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter);
|
||||
}
|
||||
pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(static_cast<uint32_t>(output_stats_barriers.size()),
|
||||
output_stats_barriers.data());
|
||||
#endif
|
||||
|
||||
|
||||
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_encode_bitstream finalized for fenceValue: %" PRIu64 "\n",
|
||||
pD3D12Enc->m_fenceValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,8 +185,11 @@ struct D3D12EncodeCapabilities
|
|||
// The maximum number of slices that the output of the current frame to be encoded will contain
|
||||
uint32_t m_MaxSlicesInOutput = 0;
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1 m_ResourceRequirementsCaps = {};
|
||||
#else
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS m_ResourceRequirementsCaps = {};
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
struct D3D12EncodeRateControlState
|
||||
|
|
@ -301,6 +304,9 @@ struct D3D12EncodeConfiguration
|
|||
std::vector<RECT> m_DirtyRectsArray;
|
||||
D3D12_VIDEO_ENCODER_MOVEREGION_INFO m_MoveRectsDesc = {};
|
||||
std::vector<D3D12_VIDEO_ENCODER_MOVE_RECT> m_MoveRectsArray;
|
||||
struct d3d12_resource *m_GPUQPStatsResource = NULL;
|
||||
struct d3d12_resource *m_GPUSATDStatsResource = NULL;
|
||||
struct d3d12_resource *m_GPURCBitAllocationStatsResource = NULL;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -585,6 +591,11 @@ d3d12_video_encoder_update_dirty_rects(struct d3d12_video_encoder *pD3D12Enc,
|
|||
void
|
||||
d3d12_video_encoder_update_move_rects(struct d3d12_video_encoder *pD3D12Enc,
|
||||
const struct pipe_enc_move_rects& rects);
|
||||
void
|
||||
d3d12_video_encoder_update_output_stats_resources(struct d3d12_video_encoder *pD3D12Enc,
|
||||
struct pipe_resource* qpmap,
|
||||
struct pipe_resource* satdmap,
|
||||
struct pipe_resource* rcbitsmap);
|
||||
///
|
||||
/// d3d12_video_encoder functions ends
|
||||
///
|
||||
|
|
|
|||
|
|
@ -912,7 +912,10 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_roi &roi_support,
|
||||
bool &bVideoEncodeRequiresTextureArray,
|
||||
union pipe_enc_cap_dirty_rect &dirty_rects_support,
|
||||
union pipe_enc_cap_move_rect &move_rects_support)
|
||||
union pipe_enc_cap_move_rect &move_rects_support,
|
||||
union pipe_enc_cap_gpu_stats_map &gpu_stats_qp,
|
||||
union pipe_enc_cap_gpu_stats_map &gpu_stats_satd,
|
||||
union pipe_enc_cap_gpu_stats_map &gpu_stats_rcbits)
|
||||
{
|
||||
ComPtr<ID3D12VideoDevice3> spD3D12VideoDevice;
|
||||
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
|
||||
|
|
@ -1115,6 +1118,79 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
move_rects_support.bits.supports_precision_quarter_pixel = (capMotionVectors.MotionUnitPrecisionSupport & D3D12_VIDEO_ENCODER_FRAME_INPUT_MOTION_UNIT_PRECISION_SUPPORT_FLAG_QUARTER_PIXEL) ? 1u : 0u;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// GPU stats caps
|
||||
/// QP Map output
|
||||
/// SATD Map output
|
||||
/// RC Bit allocation Map output
|
||||
///
|
||||
{
|
||||
gpu_stats_qp.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_QP_MAP_METADATA_AVAILABLE)) ? 1u : 0u;
|
||||
gpu_stats_satd.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_SATD_MAP_METADATA_AVAILABLE)) ? 1u : 0u;
|
||||
gpu_stats_rcbits.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_RC_BIT_ALLOCATION_MAP_METADATA_AVAILABLE )) ? 1u : 0u;
|
||||
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS optionalMetadataFlags = D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE;
|
||||
if (gpu_stats_qp.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_QP_MAP;
|
||||
if (gpu_stats_satd.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_SATD_MAP;
|
||||
if (gpu_stats_rcbits.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_RC_BIT_ALLOCATION_MAP;
|
||||
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1 capStatsResourceReqs =
|
||||
{
|
||||
// UINT NodeIndex; // input
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_CODEC Codec; // input
|
||||
sessionInfo.Codec,
|
||||
// D3D12_VIDEO_ENCODER_PROFILE_DESC Profile; // input
|
||||
sessionInfo.Profile,
|
||||
// DXGI_FORMAT InputFormat; // input
|
||||
sessionInfo.InputFormat,
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC PictureTargetResolution; // input
|
||||
sessionInfo.InputResolution,
|
||||
// BOOL IsSupported; // output
|
||||
FALSE,
|
||||
// UINT CompressedBitstreamBufferAccessAlignment; // output
|
||||
0u,
|
||||
// UINT EncoderMetadataBufferAccessAlignment; // output
|
||||
0u,
|
||||
// UINT MaxEncoderOutputMetadataBufferSize; // output
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS OptionalMetadata; // input
|
||||
optionalMetadataFlags,
|
||||
// D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION CodecConfiguration; // input
|
||||
capEncoderSupportData1.CodecConfiguration,
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataQPMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataSATDMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataBitAllocationMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
};
|
||||
|
||||
if (SUCCEEDED(spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1, &capStatsResourceReqs, sizeof(capStatsResourceReqs))))
|
||||
{
|
||||
if (gpu_stats_qp.bits.supported) {
|
||||
gpu_stats_qp.bits.pipe_pixel_format = (sessionInfo.Codec == D3D12_VIDEO_ENCODER_CODEC_AV1) ? PIPE_FORMAT_R16_SINT : PIPE_FORMAT_R8_SINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataQPMapTextureDimensions.Width)));
|
||||
gpu_stats_qp.bits.log2_values_block_size = std::log2(block_size);
|
||||
}
|
||||
|
||||
if (gpu_stats_satd.bits.supported) {
|
||||
gpu_stats_satd.bits.pipe_pixel_format = PIPE_FORMAT_R32_UINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataSATDMapTextureDimensions.Width)));
|
||||
gpu_stats_satd.bits.log2_values_block_size = std::log2(block_size);
|
||||
}
|
||||
|
||||
if (gpu_stats_rcbits.bits.supported) {
|
||||
gpu_stats_rcbits.bits.pipe_pixel_format = PIPE_FORMAT_R32_UINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataBitAllocationMapTextureDimensions.Width)));
|
||||
gpu_stats_rcbits.bits.log2_values_block_size = std::log2(block_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
|
|
@ -1491,6 +1567,79 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
move_rects_support.bits.supports_precision_quarter_pixel = (capMotionVectors.MotionUnitPrecisionSupport & D3D12_VIDEO_ENCODER_FRAME_INPUT_MOTION_UNIT_PRECISION_SUPPORT_FLAG_QUARTER_PIXEL) ? 1u : 0u;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// GPU stats caps
|
||||
/// QP Map output
|
||||
/// SATD Map output
|
||||
/// RC Bit allocation Map output
|
||||
///
|
||||
{
|
||||
gpu_stats_qp.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_QP_MAP_METADATA_AVAILABLE)) ? 1u : 0u;
|
||||
gpu_stats_satd.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_SATD_MAP_METADATA_AVAILABLE)) ? 1u : 0u;
|
||||
gpu_stats_rcbits.bits.supported = ((capEncoderSupportData1.SupportFlags & D3D12_VIDEO_ENCODER_SUPPORT_FLAG_PER_BLOCK_RC_BIT_ALLOCATION_MAP_METADATA_AVAILABLE )) ? 1u : 0u;
|
||||
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS optionalMetadataFlags = D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE;
|
||||
if (gpu_stats_qp.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_QP_MAP;
|
||||
if (gpu_stats_satd.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_SATD_MAP;
|
||||
if (gpu_stats_rcbits.bits.supported)
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_RC_BIT_ALLOCATION_MAP;
|
||||
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1 capStatsResourceReqs =
|
||||
{
|
||||
// UINT NodeIndex; // input
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_CODEC Codec; // input
|
||||
sessionInfo.Codec,
|
||||
// D3D12_VIDEO_ENCODER_PROFILE_DESC Profile; // input
|
||||
sessionInfo.Profile,
|
||||
// DXGI_FORMAT InputFormat; // input
|
||||
sessionInfo.InputFormat,
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC PictureTargetResolution; // input
|
||||
sessionInfo.InputResolution,
|
||||
// BOOL IsSupported; // output
|
||||
FALSE,
|
||||
// UINT CompressedBitstreamBufferAccessAlignment; // output
|
||||
0u,
|
||||
// UINT EncoderMetadataBufferAccessAlignment; // output
|
||||
0u,
|
||||
// UINT MaxEncoderOutputMetadataBufferSize; // output
|
||||
0u,
|
||||
// D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS OptionalMetadata; // input
|
||||
optionalMetadataFlags,
|
||||
// D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION CodecConfiguration; // input
|
||||
capEncoderSupportData1.CodecConfiguration,
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataQPMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataSATDMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
// D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC EncoderOutputMetadataBitAllocationMapTextureDimensions; // output
|
||||
{0u, 0u},
|
||||
};
|
||||
|
||||
if (SUCCEEDED(spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS1, &capStatsResourceReqs, sizeof(capStatsResourceReqs))))
|
||||
{
|
||||
if (gpu_stats_qp.bits.supported) {
|
||||
gpu_stats_qp.bits.pipe_pixel_format = (sessionInfo.Codec == D3D12_VIDEO_ENCODER_CODEC_AV1) ? PIPE_FORMAT_R16_SINT : PIPE_FORMAT_R8_SINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataQPMapTextureDimensions.Width)));
|
||||
gpu_stats_qp.bits.log2_values_block_size = static_cast<uint32_t>(std::log2(block_size));
|
||||
}
|
||||
|
||||
if (gpu_stats_satd.bits.supported) {
|
||||
gpu_stats_satd.bits.pipe_pixel_format = PIPE_FORMAT_R32_UINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataSATDMapTextureDimensions.Width)));
|
||||
gpu_stats_satd.bits.log2_values_block_size = static_cast<uint32_t>(std::log2(block_size));
|
||||
}
|
||||
|
||||
if (gpu_stats_rcbits.bits.supported) {
|
||||
gpu_stats_rcbits.bits.pipe_pixel_format = PIPE_FORMAT_R32_UINT;
|
||||
uint32_t block_size = static_cast<uint32_t>(std::ceil(capStatsResourceReqs.PictureTargetResolution.Width / static_cast<double>(capStatsResourceReqs.EncoderOutputMetadataBitAllocationMapTextureDimensions.Width)));
|
||||
gpu_stats_rcbits.bits.log2_values_block_size = static_cast<uint32_t>(std::log2(block_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -2073,6 +2222,9 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
union pipe_enc_cap_dirty_rect dirty_rects_support = {};
|
||||
union pipe_enc_cap_move_rect move_rects_support = {};
|
||||
struct d3d12_encode_codec_support codec_specific_support;
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_qp = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_satd = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_rcbits = {};
|
||||
memset(&codec_specific_support, 0, sizeof(codec_specific_support));
|
||||
switch (param) {
|
||||
case PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME:
|
||||
|
|
@ -2137,6 +2289,9 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
case PIPE_VIDEO_CAP_ENC_MAX_DPB_CAPACITY:
|
||||
case PIPE_VIDEO_CAP_ENC_DIRTY_RECTS:
|
||||
case PIPE_VIDEO_CAP_ENC_MOVE_RECTS:
|
||||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_QP_MAP:
|
||||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_SATD_MAP:
|
||||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_RATE_CONTROL_BITS_MAP:
|
||||
{
|
||||
if (d3d12_has_video_encode_support(pscreen,
|
||||
profile,
|
||||
|
|
@ -2158,7 +2313,10 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
roi_support,
|
||||
bVideoEncodeRequiresTextureArray,
|
||||
dirty_rects_support,
|
||||
move_rects_support)) {
|
||||
move_rects_support,
|
||||
gpu_stats_qp,
|
||||
gpu_stats_satd,
|
||||
gpu_stats_rcbits)) {
|
||||
|
||||
DXGI_FORMAT format = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
|
||||
auto pipeFmt = d3d12_get_pipe_format(format);
|
||||
|
|
@ -2247,6 +2405,12 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
return dirty_rects_support.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_MOVE_RECTS) {
|
||||
return move_rects_support.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_GPU_STATS_QP_MAP) {
|
||||
return gpu_stats_qp.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_GPU_STATS_SATD_MAP) {
|
||||
return gpu_stats_satd.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_GPU_STATS_RATE_CONTROL_BITS_MAP) {
|
||||
return gpu_stats_rcbits.value;
|
||||
}
|
||||
}
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_QUALITY_LEVEL) {
|
||||
|
|
@ -2317,6 +2481,9 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
memset(&codec_specific_support, 0, sizeof(codec_specific_support));
|
||||
union pipe_enc_cap_dirty_rect dirty_rects_support = {};
|
||||
union pipe_enc_cap_move_rect move_rects_support = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_qp = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_satd = {};
|
||||
union pipe_enc_cap_gpu_stats_map gpu_stats_rcbits = {};
|
||||
if (d3d12_has_video_encode_support(&pScreen->base,
|
||||
profile,
|
||||
maxLvlEncode,
|
||||
|
|
@ -2337,7 +2504,10 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
roi_support,
|
||||
bVideoEncodeRequiresTextureArray,
|
||||
dirty_rects_support,
|
||||
move_rects_support))
|
||||
move_rects_support,
|
||||
gpu_stats_qp,
|
||||
gpu_stats_satd,
|
||||
gpu_stats_rcbits))
|
||||
{
|
||||
return bVideoEncodeRequiresTextureArray;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue