diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index 9e97e89afed..dfe3c141900 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -1,4 +1,4 @@ -/* + /* * Copyright © Microsoft Corporation * * Permission is hereby granted, free of charge, to any person obtaining a @@ -415,7 +415,7 @@ static void d3d12_video_encoder_is_gpu_qmap_input_feature_enabled(struct d3d12_v void d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc, - struct pipe_resource* qpmap, + struct pipe_enc_qpmap_input_info &qpmap_info, struct pipe_enc_roi roi, uint32_t temporal_id) { @@ -429,10 +429,12 @@ d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc, // // Check if CPU/GPU QP Maps are enabled and store it in the context // - if (qpmap) + if (qpmap_info.input_qp_mode == PIPE_ENC_QPMAP_INPUT_MODE_GPU_RESOURCE && + qpmap_info.input_gpu_qpmap) { pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.AppRequested = true; - pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.InputMap = d3d12_resource(qpmap); + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.GPUInput.InputMap = + d3d12_resource(qpmap_info.input_gpu_qpmap); pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags |= D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP; } @@ -445,8 +447,34 @@ d3d12_video_encoder_update_qpmap_input(struct d3d12_video_encoder *pD3D12Enc, // 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; - } + } else if (qpmap_info.qp_map_values_count > 0 && + (qpmap_info.input_qp_mode == PIPE_ENC_QPMAP_INPUT_MODE_CPU_BUFFER_16BIT || + qpmap_info.input_qp_mode == PIPE_ENC_QPMAP_INPUT_MODE_CPU_BUFFER_8BIT)) + { + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.AppRequested = true; + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count = + qpmap_info.qp_map_values_count; + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_input_qp_mode = + static_cast(qpmap_info.input_qp_mode); + pD3D12Enc->m_currentEncodeConfig.m_encoderRateControlDesc[temporal_id].m_Flags |= + D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_DELTA_QP; + if (qpmap_info.input_qp_mode == PIPE_ENC_QPMAP_INPUT_MODE_CPU_BUFFER_8BIT && qpmap_info.input_qpmap_cpu) { + // 8-bit Path + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu = + qpmap_info.input_qpmap_cpu; + debug_printf("[d3d12_video_encoder_update_qpmap_input] Using 8-bit CPU QP Map input mode with %u QP values Map Ptr = %p.\n", + qpmap_info.qp_map_values_count, + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu); + } else if (qpmap_info.input_qp_mode == PIPE_ENC_QPMAP_INPUT_MODE_CPU_BUFFER_16BIT && qpmap_info.input_qpmap_cpu) { + // 16-bit Path + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu = + qpmap_info.input_qpmap_cpu; + debug_printf("[d3d12_video_encoder_update_qpmap_input] Using 16-bit CPU QP Map input mode with %u QP values Map Ptr = %p.\n", + qpmap_info.qp_map_values_count, + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu); + } + } #endif } @@ -2278,7 +2306,7 @@ 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_info); 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, + d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_h264_enc_picture_desc *)picture)->input_qpmap_info, ((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); @@ -2297,7 +2325,7 @@ 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_info); 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, + d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_h265_enc_picture_desc *) picture)->input_qpmap_info, ((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); @@ -2308,7 +2336,7 @@ 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, + d3d12_video_encoder_update_qpmap_input(pD3D12Enc, ((struct pipe_av1_enc_picture_desc *) picture)->input_qpmap_info, ((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 diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index dbe333734c3..87104e47181 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -255,6 +255,14 @@ struct D3D12EncodeRateControlState } }; +enum d3d12_video_encoder_input_qp_mode +{ + d3d12_video_encoder_input_disable = 0, + d3d12_video_encoder_input8_cpu_mode = 1, + d3d12_video_encoder_input16_cpu_mode = 2, + d3d12_video_encoder_input_gpu_mode = 3, +}; + struct D3D12EncodeConfiguration { d3d12_video_encoder_config_dirty_flags m_ConfigDirtyFlags = d3d12_video_encoder_config_dirty_flag_none; @@ -367,12 +375,21 @@ struct D3D12EncodeConfiguration struct d3d12_resource* InputMap; D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT capInputLayoutQPMap; } GPUInput; + // ROI map provided in CPU memory struct { bool AppRequested; // AV1 uses 16 bit integers, H26x uses 8 bit integers std::vector m_pRateControlQPMap8Bit; std::vector m_pRateControlQPMap16Bit; } CPUInput; + // When app provides a QP Map with handle and size + struct + { + bool AppRequested; + enum d3d12_video_encoder_input_qp_mode m_input_qp_mode; + void *m_p_qp_map_cpu; + uint32_t m_qp_map_count; + } CPUInputBuffer; } m_QuantizationMatrixDesc = {}; struct{ D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE MapSource; @@ -772,7 +789,7 @@ 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_qpmap_input_info &qp_info, struct pipe_enc_roi roi, uint32_t temporal_id); void diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_av1.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_av1.cpp index 1df7eb713bf..eef046ae8d7 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_av1.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_av1.cpp @@ -1647,6 +1647,15 @@ d3d12_video_encoder_update_current_frame_pic_params_info_av1(struct d3d12_video_ pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit); pAV1PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit.data(); pAV1PicData->QPMapValuesCount = static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap16Bit.size()); + } else if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.AppRequested && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count > 0 && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu) { + pAV1PicData->pRateControlQPMap = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu); + pAV1PicData->QPMapValuesCount = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count); + debug_printf("[d3d12_video_encoder_update_current_frame_pic_params_info_av1] Using user-provided CPU 16-bit QP map buffer with %d entries ptr = %p\n", + pAV1PicData->QPMapValuesCount, pAV1PicData->pRateControlQPMap); } #endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE } diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp index 80bb600078f..09f778cb85c 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_h264.cpp @@ -394,6 +394,16 @@ d3d12_video_encoder_update_current_frame_pic_params_info_h264(struct d3d12_video pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit); pH264PicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.data(); pH264PicData->QPMapValuesCount = static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.size()); + } else if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.AppRequested && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count > 0 && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu) + { + pH264PicData->pRateControlQPMap = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu); + pH264PicData->QPMapValuesCount = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count); + debug_printf("[d3d12_video_encoder_update_current_frame_pic_params_info_h264] Using user-provided CPU 8-bit QP map buffer with %d entries ptr = %p\n", + pH264PicData->QPMapValuesCount, pH264PicData->pRateControlQPMap); } #endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp index 6e47e5cc940..b10f78f373c 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc_hevc.cpp @@ -610,8 +610,19 @@ d3d12_video_encoder_update_current_frame_pic_params_info_hevc(struct d3d12_video hevc_min_delta_qp, hevc_max_delta_qp, pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit); - pHEVCPicData->pRateControlQPMap = pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.data(); - pHEVCPicData->QPMapValuesCount = static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.size()); + pHEVCPicData->pRateControlQPMap = + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.data(); + pHEVCPicData->QPMapValuesCount = static_cast( + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInput.m_pRateControlQPMap8Bit.size()); + } else if (pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.AppRequested && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count > 0 && + pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu) { + pHEVCPicData->pRateControlQPMap = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_p_qp_map_cpu); + pHEVCPicData->QPMapValuesCount = + static_cast(pD3D12Enc->m_currentEncodeConfig.m_QuantizationMatrixDesc.CPUInputBuffer.m_qp_map_count); + debug_printf("[d3d12_video_encoder_update_current_frame_pic_params_info_hevc] Using user-provided CPU 8-bit QP map buffer with %d entries ptr = %p\n", + pHEVCPicData->QPMapValuesCount, pHEVCPicData->pRateControlQPMap); } #endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE @@ -1669,4 +1680,4 @@ d3d12_video_encoder_count_valid_reflist_entries_hevc(const pipe_h265_enc_picture break; } } -} \ No newline at end of file +} diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 9f99252e55e..dc70f5c7e8e 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -986,7 +986,6 @@ struct pipe_h264_enc_picture_desc /* See PIPE_VIDEO_CAP_ENC_GPU_STATS_PSNR */ struct pipe_resource *gpu_stats_psnr; - struct pipe_resource *input_gpu_qpmap; // to be removed. struct pipe_enc_qpmap_input_info input_qpmap_info; bool not_referenced; @@ -1386,7 +1385,6 @@ struct pipe_h265_enc_picture_desc /* See PIPE_VIDEO_CAP_ENC_GPU_STATS_PSNR */ struct pipe_resource *gpu_stats_psnr; - struct pipe_resource *input_gpu_qpmap; // to be remove struct pipe_enc_qpmap_input_info input_qpmap_info; unsigned num_ref_idx_l0_active_minus1; @@ -1570,7 +1568,6 @@ struct pipe_av1_enc_picture_desc struct pipe_enc_quality_modes quality_modes; struct pipe_enc_intra_refresh intra_refresh; struct pipe_enc_roi roi; - struct pipe_resource *input_gpu_qpmap; // to be removed struct pipe_enc_qpmap_input_info input_qpmap_info; uint32_t tile_rows; uint32_t tile_cols;