mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 19:40:10 +01:00
d3d12: Add GPU input dirty rect support
Reviewed-By: Pohsiang Hsu <pohhsu@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34844>
This commit is contained in:
parent
86d521db4f
commit
5cb4979875
3 changed files with 244 additions and 29 deletions
|
|
@ -390,22 +390,47 @@ d3d12_video_encoder_update_dirty_rects(struct d3d12_video_encoder *pD3D12Enc,
|
|||
const struct pipe_enc_dirty_info& rects)
|
||||
{
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.SourceDPBFrameReference = rects.dpb_reference_index;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.FullFrameIdentical = rects.full_frame_skip;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapValuesType =
|
||||
(rects.dirty_info_type == PIPE_ENC_DIRTY_INFO_TYPE_DIRTY) ? D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_DIRTY :
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_SKIP;
|
||||
memset(&pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc, 0, sizeof(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc));
|
||||
|
||||
assert(rects.num_rects <= PIPE_ENC_DIRTY_RECTS_NUM_MAX);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.NumDirtyRects = std::min(rects.num_rects, static_cast<uint32_t>(PIPE_ENC_DIRTY_RECTS_NUM_MAX));
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray.resize(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.NumDirtyRects);
|
||||
for (uint32_t i = 0; i < pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.NumDirtyRects; i++) {
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].top = rects.rects[i].top;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].left = rects.rects[i].left;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].right = rects.rects[i].right;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].bottom = rects.rects[i].bottom;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapSource = rects.input_mode == PIPE_ENC_DIRTY_INFO_INPUT_MODE_RECTS ?
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER : D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE;
|
||||
|
||||
if(rects.input_mode == PIPE_ENC_DIRTY_INFO_INPUT_MODE_RECTS)
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.SourceDPBFrameReference = rects.dpb_reference_index;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.FullFrameIdentical = rects.full_frame_skip;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.MapValuesType =
|
||||
(rects.dirty_info_type == PIPE_ENC_DIRTY_INFO_TYPE_DIRTY) ? D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_DIRTY :
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_SKIP;
|
||||
|
||||
if (!pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.FullFrameIdentical)
|
||||
{
|
||||
assert(rects.num_rects <= PIPE_ENC_DIRTY_RECTS_NUM_MAX);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.NumDirtyRects = std::min(rects.num_rects, static_cast<uint32_t>(PIPE_ENC_DIRTY_RECTS_NUM_MAX));
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray.resize(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.NumDirtyRects);
|
||||
for (uint32_t i = 0; i < pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.NumDirtyRects; i++) {
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].top = rects.rects[i].top;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].left = rects.rects[i].left;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].right = rects.rects[i].right;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray[i].bottom = rects.rects[i].bottom;
|
||||
}
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.pDirtyRects = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray.data();
|
||||
}
|
||||
}
|
||||
else if (rects.input_mode == PIPE_ENC_DIRTY_INFO_INPUT_MODE_MAP)
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.SourceDPBFrameReference = rects.dpb_reference_index;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical = rects.full_frame_skip;
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.MapValuesType =
|
||||
(rects.dirty_info_type == PIPE_ENC_DIRTY_INFO_TYPE_DIRTY) ? D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_DIRTY :
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_SKIP;
|
||||
|
||||
assert(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical || rects.map);
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.InputMap =
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical ? NULL : d3d12_resource(rects.map);
|
||||
assert(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical ||
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.InputMap);
|
||||
}
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.pDirtyRects = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsArray.data();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +537,7 @@ d3d12_video_encoder_reconfigure_encoder_objects(struct d3d12_video_encoder *pD3D
|
|||
d3d12_video_encoder_config_dirty_flag_motion_precision_limit) != 0);
|
||||
bool irChanged = ((pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags &
|
||||
d3d12_video_encoder_config_dirty_flag_intra_refresh) != 0);
|
||||
bool dirtyRegionsChanged = ((pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags &
|
||||
[[maybe_unused]] bool dirtyRegionsChanged = ((pD3D12Enc->m_currentEncodeConfig.m_ConfigDirtyFlags &
|
||||
d3d12_video_encoder_config_dirty_flag_dirty_regions) != 0);
|
||||
|
||||
// Events that that trigger a re-creation of the reference picture manager
|
||||
|
|
@ -639,7 +664,9 @@ d3d12_video_encoder_reconfigure_encoder_objects(struct d3d12_video_encoder *pD3D
|
|||
0 /*checking the flag is NOT set*/))
|
||||
// || motionPrecisionLimitChanged // Only affects encoder
|
||||
// Re-create encoder heap if dirty regions changes and the current heap doesn't already support them
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|| dirtyRegionsChanged && ((pD3D12Enc->m_spVideoEncoderHeap->GetEncoderHeapFlags() & D3D12_VIDEO_ENCODER_HEAP_FLAG_ALLOW_DIRTY_REGIONS) == 0)
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
) {
|
||||
if (!pD3D12Enc->m_spVideoEncoderHeap) {
|
||||
debug_printf("[d3d12_video_encoder] d3d12_video_encoder_reconfigure_encoder_objects - Creating "
|
||||
|
|
@ -1296,6 +1323,27 @@ d3d12_video_encoder_disable_rc_minmaxqp(struct D3D12EncodeRateControlState & rcS
|
|||
}
|
||||
}
|
||||
|
||||
static bool d3d12_video_encoder_is_dirty_regions_feature_enabled(struct d3d12_video_encoder* pD3D12Enc, D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE mapSource)
|
||||
{
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapSource != mapSource)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER)
|
||||
{
|
||||
return pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.FullFrameIdentical ||
|
||||
(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.NumDirtyRects > 0);
|
||||
}
|
||||
else if (mapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE)
|
||||
{
|
||||
return pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical ||
|
||||
(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.InputMap != NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
|
||||
static void
|
||||
d3d12_video_encoder_disable_rc_extended1_to_legacy(struct D3D12EncodeRateControlState & rcState)
|
||||
{
|
||||
|
|
@ -1497,9 +1545,14 @@ bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3
|
|||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
// Set dirty regions input info to cap
|
||||
capEncoderSupportData1.DirtyRegions.Enabled = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.FullFrameIdentical || (pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.NumDirtyRects > 0);
|
||||
capEncoderSupportData1.DirtyRegions.MapSource = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
capEncoderSupportData1.DirtyRegions.MapValuesType = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapValuesType;
|
||||
capEncoderSupportData1.DirtyRegions.MapSource = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapSource;
|
||||
capEncoderSupportData1.DirtyRegions.Enabled = d3d12_video_encoder_is_dirty_regions_feature_enabled(pD3D12Enc, pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapSource);
|
||||
if (capEncoderSupportData1.DirtyRegions.Enabled)
|
||||
{
|
||||
capEncoderSupportData1.DirtyRegions.MapValuesType = (capEncoderSupportData1.DirtyRegions.MapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER) ?
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo.MapValuesType :
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.MapValuesType;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum pipe_video_format codec = u_reduce_video_profile(pD3D12Enc->base.profile);
|
||||
|
|
@ -1619,6 +1672,45 @@ bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3
|
|||
|
||||
pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags = capEncoderSupportData1.SupportFlags;
|
||||
pD3D12Enc->m_currentEncodeCapabilities.m_ValidationFlags = capEncoderSupportData1.ValidationFlags;
|
||||
|
||||
if ((capEncoderSupportData1.DirtyRegions.MapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE) &&
|
||||
(capEncoderSupportData1.DirtyRegions.Enabled))
|
||||
{
|
||||
// Query specifics of staging resource for dirty regions
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion =
|
||||
{
|
||||
// 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_DIRTY_REGIONS,
|
||||
// BOOL IsSupported;
|
||||
FALSE,
|
||||
// UINT64 MaxResolvedBufferAllocationSize;
|
||||
0u,
|
||||
};
|
||||
|
||||
hr = pD3D12Enc->m_spD3D12VideoDevice->CheckFeatureSupport(D3D12_FEATURE_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT,
|
||||
&pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion,
|
||||
sizeof(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
debug_printf("CheckFeatureSupport D3D12_FEATURE_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT failed with HR %x\n", hr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2028,6 +2120,39 @@ d3d12_video_encoder_prepare_output_buffers(struct d3d12_video_encoder *pD3D12Enc
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
d3d12_video_encoder_prepare_input_buffers(struct d3d12_video_encoder *pD3D12Enc)
|
||||
{
|
||||
// Go over any features that may need additional input buffers
|
||||
// and create them on demand (if the previous allocation is not big enough)
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
D3D12_HEAP_PROPERTIES Properties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
|
||||
if (d3d12_video_encoder_is_dirty_regions_feature_enabled(pD3D12Enc, D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE))
|
||||
{
|
||||
bool bNeedsCreation = (pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spDirtyRectsResolvedOpaqueMap == NULL) ||
|
||||
(GetDesc(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spDirtyRectsResolvedOpaqueMap.Get()).Width <
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion.MaxResolvedBufferAllocationSize);
|
||||
if (bNeedsCreation)
|
||||
{
|
||||
pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spDirtyRectsResolvedOpaqueMap.Reset();
|
||||
CD3DX12_RESOURCE_DESC subregionOffsetsDesc = CD3DX12_RESOURCE_DESC::Buffer(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion.MaxResolvedBufferAllocationSize);
|
||||
hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommittedResource(&Properties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&subregionOffsetsDesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spDirtyRectsResolvedOpaqueMap));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
debug_printf("CreateCommittedResource for m_spDirtyRectsResolvedOpaqueMap failed with HR %x\n", hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
bool
|
||||
d3d12_video_encoder_reconfigure_session(struct d3d12_video_encoder *pD3D12Enc,
|
||||
struct pipe_video_buffer * srcTexture,
|
||||
|
|
@ -2051,6 +2176,10 @@ d3d12_video_encoder_reconfigure_session(struct d3d12_video_encoder *pD3D12Enc,
|
|||
debug_printf("d3d12_video_encoder_prepare_output_buffers failed!\n");
|
||||
return false;
|
||||
}
|
||||
if(!d3d12_video_encoder_prepare_input_buffers(pD3D12Enc)) {
|
||||
debug_printf("d3d12_video_encoder_prepare_input_buffers failed!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save frame size expectation snapshot from record time to resolve at get_feedback time (after execution)
|
||||
size_t current_metadata_slot = d3d12_video_encoder_metadata_current_index(pD3D12Enc);
|
||||
|
|
@ -2761,11 +2890,66 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
|||
#endif
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
std::vector<D3D12_RESOURCE_BARRIER> pResolveInputDataBarriers;
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS dirtyRegions = { };
|
||||
dirtyRegions.MapSource = D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER;
|
||||
dirtyRegions.pCPUBuffer = &pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc;
|
||||
if (dirtyRegions.pCPUBuffer->NumDirtyRects > 0)
|
||||
dirtyRegions.MapSource = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapSource;
|
||||
|
||||
if (d3d12_video_encoder_is_dirty_regions_feature_enabled(pD3D12Enc, dirtyRegions.MapSource))
|
||||
{
|
||||
picCtrlFlags |= D3D12_VIDEO_ENCODER_PICTURE_CONTROL_FLAG_ENABLE_DIRTY_REGIONS_INPUT;
|
||||
if (dirtyRegions.MapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER)
|
||||
{
|
||||
dirtyRegions.pCPUBuffer = &pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.RectsInfo;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical)
|
||||
{
|
||||
// When this parameter is TRUE, pDirtyRects must be NULL and the driver will interpret it
|
||||
// as a dirty regions map being present and an all-zero matrix in mode D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_DIRTY.
|
||||
dirtyRegions.pCPUBuffer->pDirtyRects = NULL;
|
||||
}
|
||||
}
|
||||
else if (dirtyRegions.MapSource == D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE)
|
||||
{
|
||||
dirtyRegions.pOpaqueLayoutBuffer = pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spDirtyRectsResolvedOpaqueMap.Get();
|
||||
|
||||
pResolveInputDataBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(dirtyRegions.pOpaqueLayoutBuffer,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE));
|
||||
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.InputMap)
|
||||
{
|
||||
assert(!pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical); // When this parameter is TRUE, pDirtyRegionsMap must be NULL
|
||||
pResolveInputDataBarriers.push_back(CD3DX12_RESOURCE_BARRIER::Transition(d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.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_DIRTY_REGIONS;
|
||||
ResolveInputData.DirtyRegions.FullFrameIdentical = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical;
|
||||
ResolveInputData.DirtyRegions.pDirtyRegionsMap = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.FullFrameIdentical ? NULL : d3d12_resource_resource(pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.InputMap);
|
||||
ResolveInputData.DirtyRegions.MapValuesType = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.MapValuesType;
|
||||
ResolveInputData.DirtyRegions.SourceDPBFrameReference = pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.SourceDPBFrameReference;
|
||||
D3D12_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT_INPUT_ARGUMENTS resolveInputParamLayoutInput =
|
||||
{
|
||||
pD3D12Enc->m_currentEncodeConfig.m_DirtyRectsDesc.MapInfo.capInputLayoutDirtyRegion.SessionInfo,
|
||||
ResolveInputData,
|
||||
};
|
||||
D3D12_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT_OUTPUT_ARGUMENTS resolveInputParamLayoutOutput =
|
||||
{
|
||||
dirtyRegions.pOpaqueLayoutBuffer,
|
||||
};
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -323,7 +323,22 @@ struct D3D12EncodeConfiguration
|
|||
bool m_bUsedAsReference; // Set if frame will be used as reference frame
|
||||
|
||||
#if D3D12_VIDEO_USE_NEW_ENCODECMDLIST4_INTERFACE
|
||||
D3D12_VIDEO_ENCODER_DIRTY_RECT_INFO m_DirtyRectsDesc = {};
|
||||
struct{
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE MapSource;
|
||||
union {
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER
|
||||
D3D12_VIDEO_ENCODER_DIRTY_RECT_INFO RectsInfo;
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE
|
||||
struct
|
||||
{
|
||||
BOOL FullFrameIdentical;
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE MapValuesType;
|
||||
struct d3d12_resource* InputMap;
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLVE_INPUT_PARAM_LAYOUT capInputLayoutDirtyRegion;
|
||||
UINT SourceDPBFrameReference;
|
||||
} MapInfo;
|
||||
};
|
||||
} m_DirtyRectsDesc = {};
|
||||
std::vector<RECT> m_DirtyRectsArray;
|
||||
D3D12_VIDEO_ENCODER_MOVEREGION_INFO m_MoveRectsDesc = {};
|
||||
std::vector<D3D12_VIDEO_ENCODER_MOVE_RECT> m_MoveRectsArray;
|
||||
|
|
@ -505,6 +520,8 @@ struct d3d12_video_encoder
|
|||
|
||||
/* Stores encode result for submission error control in the D3D12_VIDEO_ENC_ASYNC_DEPTH slots */
|
||||
enum pipe_video_feedback_encode_result_flags encode_result = PIPE_VIDEO_FEEDBACK_METADATA_ENCODE_FLAG_OK;
|
||||
|
||||
ComPtr<ID3D12Resource> m_spDirtyRectsResolvedOpaqueMap; // output of ID3D12VideoEncodeCommandList::ResolveInputParamLayout
|
||||
};
|
||||
|
||||
std::vector<InFlightEncodeResources> m_inflightResourcesPool;
|
||||
|
|
@ -642,6 +659,9 @@ d3d12_video_encoder_update_output_stats_resources(struct d3d12_video_encoder *pD
|
|||
struct pipe_resource* qpmap,
|
||||
struct pipe_resource* satdmap,
|
||||
struct pipe_resource* rcbitsmap);
|
||||
|
||||
bool
|
||||
d3d12_video_encoder_prepare_input_buffers(struct d3d12_video_encoder *pD3D12Enc);
|
||||
///
|
||||
/// d3d12_video_encoder functions ends
|
||||
///
|
||||
|
|
|
|||
|
|
@ -896,7 +896,8 @@ static d3d12_video_encode_get_hevc_codec_support ( const D3D12_VIDEO_ENCODER_COD
|
|||
static
|
||||
union pipe_enc_cap_dirty_info
|
||||
get_dirty_rects_support(D3D12_VIDEO_ENCODER_INPUT_MAP_SESSION_INFO sessionInfo,
|
||||
ID3D12VideoDevice3* pD3D12VideoDevice)
|
||||
ID3D12VideoDevice3* pD3D12VideoDevice,
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE mapSource)
|
||||
{
|
||||
D3D12_FEATURE_DATA_VIDEO_ENCODER_DIRTY_REGIONS capDirtyRegions =
|
||||
{
|
||||
|
|
@ -904,7 +905,7 @@ get_dirty_rects_support(D3D12_VIDEO_ENCODER_INPUT_MAP_SESSION_INFO sessionInfo,
|
|||
0u,
|
||||
sessionInfo,
|
||||
// D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE MapSource;
|
||||
D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER,
|
||||
mapSource,
|
||||
// D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE MapValuesType;
|
||||
D3D12_VIDEO_ENCODER_DIRTY_REGIONS_MAP_VALUES_MODE_DIRTY,
|
||||
// D3D12_VIDEO_ENCODER_DIRTY_REGIONS_SUPPORT_FLAGS SupportFlags;
|
||||
|
|
@ -1088,7 +1089,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
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,
|
||||
union pipe_enc_cap_sliced_notifications &sliced_encode_support)
|
||||
union pipe_enc_cap_sliced_notifications &sliced_encode_support,
|
||||
union pipe_enc_cap_dirty_info &dirty_rects_support_gpu)
|
||||
{
|
||||
ComPtr<ID3D12VideoDevice3> spD3D12VideoDevice;
|
||||
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pscreen;
|
||||
|
|
@ -1217,7 +1219,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
capEncoderSupportData1.SubregionFrameEncodingData,
|
||||
};
|
||||
|
||||
dirty_rects_support = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get());
|
||||
dirty_rects_support = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get(), D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER);
|
||||
dirty_rects_support_gpu = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get(), D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE);
|
||||
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);
|
||||
|
|
@ -1524,7 +1527,8 @@ d3d12_has_video_encode_support(struct pipe_screen *pscreen,
|
|||
capEncoderSupportData1.SubregionFrameEncodingData,
|
||||
};
|
||||
|
||||
dirty_rects_support = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get());
|
||||
dirty_rects_support = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get(), D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_CPU_BUFFER);
|
||||
dirty_rects_support_gpu = get_dirty_rects_support(sessionInfo, spD3D12VideoDevice.Get(), D3D12_VIDEO_ENCODER_INPUT_MAP_SOURCE_GPU_TEXTURE);
|
||||
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);
|
||||
|
|
@ -2108,6 +2112,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
uint32_t maxIRDuration = 0u;
|
||||
union pipe_enc_cap_roi roi_support = {};
|
||||
union pipe_enc_cap_dirty_info dirty_rects_support = {};
|
||||
union pipe_enc_cap_dirty_info dirty_rects_support_gpu = {};
|
||||
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 = {};
|
||||
|
|
@ -2182,6 +2187,7 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
case PIPE_VIDEO_CAP_ENC_GPU_STATS_SATD_MAP:
|
||||
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:
|
||||
{
|
||||
if (d3d12_has_video_encode_support(pscreen,
|
||||
profile,
|
||||
|
|
@ -2207,7 +2213,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
gpu_stats_qp,
|
||||
gpu_stats_satd,
|
||||
gpu_stats_rcbits,
|
||||
sliced_encode_support)) {
|
||||
sliced_encode_support,
|
||||
dirty_rects_support_gpu)) {
|
||||
|
||||
DXGI_FORMAT format = d3d12_convert_pipe_video_profile_to_dxgi_format(profile);
|
||||
auto pipeFmt = d3d12_get_pipe_format(format);
|
||||
|
|
@ -2304,6 +2311,8 @@ d3d12_screen_get_video_param_encode(struct pipe_screen *pscreen,
|
|||
return gpu_stats_rcbits.value;
|
||||
} else if (param == PIPE_VIDEO_CAP_ENC_SLICED_NOTIFICATIONS) {
|
||||
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_QUALITY_LEVEL) {
|
||||
|
|
@ -2373,6 +2382,7 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
struct d3d12_encode_codec_support codec_specific_support;
|
||||
memset(&codec_specific_support, 0, sizeof(codec_specific_support));
|
||||
union pipe_enc_cap_dirty_info dirty_rects_support = {};
|
||||
union pipe_enc_cap_dirty_info dirty_rects_support_gpu = {};
|
||||
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 = {};
|
||||
|
|
@ -2402,7 +2412,8 @@ d3d12_video_encode_requires_texture_array_dpb(struct d3d12_screen* pScreen, enum
|
|||
gpu_stats_qp,
|
||||
gpu_stats_satd,
|
||||
gpu_stats_rcbits,
|
||||
sliced_encode_support))
|
||||
sliced_encode_support,
|
||||
dirty_rects_support_gpu))
|
||||
{
|
||||
return bVideoEncodeRequiresTextureArray;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue