diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index 73cfae1bbb5..f569d2e32ff 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -155,10 +155,19 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec) goto flush_fail; } + hr = pD3D12Enc->m_spResolveCommandList->Close(); + if (FAILED(hr)) { + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_flush - Can't close command list with HR %x\n", (unsigned)hr); + goto flush_fail; + } + ID3D12CommandList *ppCommandLists[1] = { pD3D12Enc->m_spEncodeCommandList.Get() }; pD3D12Enc->m_spEncodeCommandQueue->ExecuteCommandLists(1, ppCommandLists); + pD3D12Enc->m_spEncodeCommandQueue->Signal(pD3D12Enc->m_spLastSliceFence.Get(), pD3D12Enc->m_LastSliceFenceValue); + ID3D12CommandList *ppCommandLists2[1] = { pD3D12Enc->m_spResolveCommandList.Get() }; + pD3D12Enc->m_spEncodeCommandQueue->ExecuteCommandLists(1, ppCommandLists2); pD3D12Enc->m_spEncodeCommandQueue->Signal(pD3D12Enc->m_spFence.Get(), pD3D12Enc->m_fenceValue); - + // Validate device was not removed hr = pD3D12Enc->m_pD3D12Screen->dev->GetDeviceRemovedReason(); if (hr != S_OK) { @@ -170,6 +179,7 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec) } pD3D12Enc->m_fenceValue++; + pD3D12Enc->m_LastSliceFenceValue++; pD3D12Enc->m_bPendingWorkNotFlushed = false; } return; @@ -204,6 +214,14 @@ d3d12_video_encoder_sync_completion(struct pipe_video_codec *codec, goto sync_with_token_fail; } + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_sync_completion - resetting ID3D12CommandAllocator %p...\n", + pool_entry.m_spResolveCommandAllocator.Get()); + hr = pool_entry.m_spResolveCommandAllocator->Reset(); + if(FAILED(hr)) { + debug_printf("failed with %x.\n", (unsigned)hr); + goto sync_with_token_fail; + } + // Release references granted on end_frame for this inflight operations pool_entry.m_spEncoder.Reset(); pool_entry.m_spEncoderHeap.Reset(); @@ -2343,6 +2361,14 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } + hr = pD3D12Enc->m_pD3D12Screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&pD3D12Enc->m_spLastSliceFence)); + if (FAILED(hr)) { + debug_printf( + "[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to CreateFence failed with HR %x\n", + (unsigned)hr); + return false; + } + uint64_t CompletionFenceValue = pD3D12Enc->m_fenceValue; for (auto& inputResource : pD3D12Enc->m_inflightResourcesPool) { @@ -2357,8 +2383,21 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } + // Create associated command allocator for Resolve operations + hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, + IID_PPV_ARGS(inputResource.m_spResolveCommandAllocator.GetAddressOf())); + if (FAILED(hr)) { + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to " + "CreateCommandAllocator failed with HR %x\n", + (unsigned)hr); + return false; + } + // Initialize fence for the in flight resource pool slot - inputResource.m_CompletionFence.reset(d3d12_create_fence_raw(pD3D12Enc->m_spFence.Get(), CompletionFenceValue++)); + inputResource.m_CompletionFence.reset(d3d12_create_fence_raw(pD3D12Enc->m_spFence.Get(), CompletionFenceValue)); + inputResource.m_CompletionFence.reset(d3d12_create_fence_raw(pD3D12Enc->m_spLastSliceFence.Get(), CompletionFenceValue)); + CompletionFenceValue++; } ComPtr spD3D12Device4; @@ -2381,6 +2420,18 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } + hr = spD3D12Device4->CreateCommandList1(0, + D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, + D3D12_COMMAND_LIST_FLAG_NONE, + IID_PPV_ARGS(pD3D12Enc->m_spResolveCommandList.GetAddressOf())); + + if (FAILED(hr)) { + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to CreateCommandList " + "failed with HR %x\n", + (unsigned)hr); + return false; + } + return true; } @@ -2825,6 +2876,14 @@ d3d12_video_encoder_begin_frame(struct pipe_video_codec * codec, goto fail; } + hr = pD3D12Enc->m_spResolveCommandList->Reset(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spResolveCommandAllocator.Get()); + if (FAILED(hr)) { + debug_printf( + "[d3d12_video_encoder] d3d12_video_encoder_flush - resetting ID3D12GraphicsCommandList failed with HR %x\n", + (unsigned)hr); + goto fail; + } + pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFence = d3d12_fence(picture->in_fence); pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_InputSurfaceFenceValue = picture->in_fence_value; pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].encode_result = PIPE_VIDEO_FEEDBACK_METADATA_ENCODE_FLAG_OK; @@ -3319,6 +3378,9 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, *feedback = (void*)pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].m_fence.get(); + pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].m_LastSliceFence.reset(d3d12_create_fence_raw(pD3D12Enc->m_spLastSliceFence.Get(), pD3D12Enc->m_LastSliceFenceValue)); + d3d12_fence_reference((struct d3d12_fence **)last_slice_completion_fence, pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].m_LastSliceFence.get()); + std::vector rgCurrentFrameStateTransitions = { CD3DX12_RESOURCE_BARRIER::Transition(pInputVideoD3D12Res, D3D12_RESOURCE_STATE_COMMON, @@ -3489,8 +3551,11 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, #endif ComPtr spEncodeCommandList4; - if (SUCCEEDED(pD3D12Enc->m_spEncodeCommandList->QueryInterface( - IID_PPV_ARGS(spEncodeCommandList4.GetAddressOf())))) { + ComPtr spResolveCommandList4; + if ((SUCCEEDED(pD3D12Enc->m_spEncodeCommandList->QueryInterface( + IID_PPV_ARGS(spEncodeCommandList4.GetAddressOf())))) && + (SUCCEEDED(pD3D12Enc->m_spResolveCommandList->QueryInterface( + IID_PPV_ARGS(spResolveCommandList4.GetAddressOf()))))) { // Update current frame pic params state after reconfiguring above. D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA1 currentPicParams = @@ -4049,7 +4114,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_COMMON)); } - spEncodeCommandList4->ResourceBarrier(static_cast(rgResolveMetadataStateTransitions.size()), + spResolveCommandList4->ResourceBarrier(static_cast(rgResolveMetadataStateTransitions.size()), rgResolveMetadataStateTransitions.data()); std::vector output_stats_barriers; @@ -4077,7 +4142,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE)); } - spEncodeCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), + spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), output_stats_barriers.data()); const D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS1 inputMetadataCmd = { pD3D12Enc->m_currentEncodeConfig.m_encoderCodecDesc, @@ -4112,7 +4177,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, {}, }; - spEncodeCommandList4->ResolveEncoderOutputMetadata1(&inputMetadataCmd, &outputMetadataCmd); + spResolveCommandList4->ResolveEncoderOutputMetadata1(&inputMetadataCmd, &outputMetadataCmd); debug_printf("[d3d12_video_encoder_encode_bitstream] EncodeFrame slot %" PRIu64 " encoder %p encoderheap %p input tex %p output bitstream %p raw metadata buf %p resolved metadata buf %p Command allocator %p\n", static_cast(d3d12_video_encoder_pool_current_index(pD3D12Enc)), @@ -4146,14 +4211,14 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_COMMON), }; - spEncodeCommandList4->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), + spResolveCommandList4->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), rgRevertResolveMetadataStateTransitions); // Revert output_stats_barriers for (auto &BarrierDesc : output_stats_barriers) { std::swap(BarrierDesc.Transition.StateBefore, BarrierDesc.Transition.StateAfter); } - spEncodeCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), + spResolveCommandList4->ResourceBarrier(static_cast(output_stats_barriers.size()), output_stats_barriers.data()); for (auto &BarrierDesc : pSlicedEncodingExtraBarriers) { @@ -4218,6 +4283,24 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, &inputStreamArguments, &outputStreamArguments); + std::vector rgResolveMetadataStateTransitions = { + CD3DX12_RESOURCE_BARRIER::Transition(pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].spBuffer.Get(), + D3D12_RESOURCE_STATE_COMMON, + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE), + CD3DX12_RESOURCE_BARRIER::Transition(pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].m_spMetadataOutputBuffer.Get(), + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, + D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ), + CD3DX12_RESOURCE_BARRIER::Transition(pInputVideoD3D12Res, + D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ, + D3D12_RESOURCE_STATE_COMMON), + CD3DX12_RESOURCE_BARRIER::Transition(pOutputBufferD3D12Resources[0], + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, + D3D12_RESOURCE_STATE_COMMON), + }; + + pD3D12Enc->m_spResolveCommandList->ResourceBarrier(static_cast(rgResolveMetadataStateTransitions.size()), + rgResolveMetadataStateTransitions.data()); + const D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS inputMetadataCmd = { pD3D12Enc->m_currentEncodeConfig.m_encoderCodecDesc, d3d12_video_encoder_get_current_profile_desc(pD3D12Enc), @@ -4232,7 +4315,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, { pD3D12Enc->m_spEncodedFrameMetadata[current_metadata_slot].spBuffer.Get(), 0 } }; - pD3D12Enc->m_spEncodeCommandList->ResolveEncoderOutputMetadata(&inputMetadataCmd, &outputMetadataCmd); + pD3D12Enc->m_spResolveCommandList->ResolveEncoderOutputMetadata(&inputMetadataCmd, &outputMetadataCmd); debug_printf("[d3d12_video_encoder_encode_bitstream] EncodeFrame slot %" PRIu64 " encoder %p encoderheap %p input tex %p output bitstream %p raw metadata buf %p resolved metadata buf %p Command allocator %p\n", static_cast(d3d12_video_encoder_pool_current_index(pD3D12Enc)), @@ -4266,7 +4349,7 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec, D3D12_RESOURCE_STATE_COMMON), }; - pD3D12Enc->m_spEncodeCommandList->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), + pD3D12Enc->m_spResolveCommandList->ResourceBarrier(_countof(rgRevertResolveMetadataStateTransitions), rgRevertResolveMetadataStateTransitions); } debug_printf("[d3d12_video_encoder] d3d12_video_encoder_encode_bitstream finalized for fenceValue: %" PRIu64 "\n", diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index d1a37495f6f..ce5d3ee67e5 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -546,6 +546,7 @@ struct EncodedBitstreamResolvedMetadata /* Pending fence data for this frame */ d3d12_unique_fence m_fence; + d3d12_unique_fence m_LastSliceFence; }; enum d3d12_video_encoder_driver_workarounds @@ -580,7 +581,9 @@ struct d3d12_video_encoder size_t m_MaxMetadataBuffersCount = 0; ComPtr m_spFence; + ComPtr m_spLastSliceFence; uint64_t m_fenceValue = 1u; + uint64_t m_LastSliceFenceValue = 1u; bool m_bPendingWorkNotFlushed = false; ComPtr m_spD3D12VideoDevice; @@ -588,6 +591,7 @@ struct d3d12_video_encoder ComPtr m_spVideoEncoderHeap; ComPtr m_spEncodeCommandQueue; ComPtr m_spEncodeCommandList; + ComPtr m_spResolveCommandList; std::vector m_transitionsBeforeCloseCmdList; std::unique_ptr m_upDPBManager; @@ -614,6 +618,7 @@ struct d3d12_video_encoder std::shared_ptr m_References; ComPtr m_spCommandAllocator; + ComPtr m_spResolveCommandAllocator; struct d3d12_fence* m_InputSurfaceFence = NULL; uint64_t m_InputSurfaceFenceValue = 0;