diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index 99f8cb8dda5..f50920cfaac 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -47,6 +47,12 @@ #include +uint64_t +d3d12_video_encoder_pool_current_index(struct d3d12_video_encoder *pD3D12Enc) +{ + return pD3D12Enc->m_fenceValue % D3D12_VIDEO_ENC_ASYNC_DEPTH; +} + /** * flush any outstanding command buffers to the hardware * should be called before a video_buffer is acessed by the gallium frontend again @@ -108,7 +114,7 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec) "fenceValue: %" PRIu64 "\n", pD3D12Enc->m_fenceValue); - hr = pD3D12Enc->m_spCommandAllocator->Reset(); + hr = pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spCommandAllocator->Reset(); if (FAILED(hr)) { debug_printf( "[d3d12_video_encoder] d3d12_video_encoder_flush - resetting ID3D12CommandAllocator failed with HR %x\n", @@ -116,14 +122,6 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec) goto flush_fail; } - hr = pD3D12Enc->m_spEncodeCommandList->Reset(pD3D12Enc->m_spCommandAllocator.Get()); - if (FAILED(hr)) { - debug_printf( - "[d3d12_video_encoder] d3d12_video_encoder_flush - resetting ID3D12GraphicsCommandList failed with HR %x\n", - hr); - goto flush_fail; - } - // Validate device was not removed hr = pD3D12Enc->m_pD3D12Screen->dev->GetDeviceRemovedReason(); if (hr != S_OK) { @@ -966,22 +964,32 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc return false; } - hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, - IID_PPV_ARGS(pD3D12Enc->m_spCommandAllocator.GetAddressOf())); - if (FAILED(hr)) { - debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to " - "CreateCommandAllocator failed with HR %x\n", - hr); + for (auto& inputResource : pD3D12Enc->m_inflightResourcesPool) + { + // Create associated command allocator for Encode, Resolve operations + hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, + IID_PPV_ARGS(inputResource.m_spCommandAllocator.GetAddressOf())); + if (FAILED(hr)) { + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to " + "CreateCommandAllocator failed with HR %x\n", + hr); + return false; + } + } + + ComPtr spD3D12Device4; + if (FAILED(pD3D12Enc->m_pD3D12Screen->dev->QueryInterface( + IID_PPV_ARGS(spD3D12Device4.GetAddressOf())))) { + debug_printf( + "[d3d12_video_encoder] d3d12_video_encoder_create_encoder - D3D12 Device has no Video encode support\n"); return false; } - hr = - pD3D12Enc->m_pD3D12Screen->dev->CreateCommandList(0, - D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, - pD3D12Enc->m_spCommandAllocator.Get(), - nullptr, - IID_PPV_ARGS(pD3D12Enc->m_spEncodeCommandList.GetAddressOf())); + hr = spD3D12Device4->CreateCommandList1(0, + D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, + D3D12_COMMAND_LIST_FLAG_NONE, + IID_PPV_ARGS(pD3D12Enc->m_spEncodeCommandList.GetAddressOf())); if (FAILED(hr)) { debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to CreateCommandList " @@ -1004,6 +1012,7 @@ d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pi struct d3d12_video_encoder *pD3D12Enc = new d3d12_video_encoder; pD3D12Enc->m_spEncodedFrameMetadata.resize(D3D12_VIDEO_ENC_METADATA_BUFFERS_COUNT, {nullptr, 0, 0}); + pD3D12Enc->m_inflightResourcesPool.resize(D3D12_VIDEO_ENC_ASYNC_DEPTH, { 0 }); pD3D12Enc->base = *codec; pD3D12Enc->m_screen = context->screen; @@ -1156,6 +1165,7 @@ d3d12_video_encoder_begin_frame(struct pipe_video_codec * codec, // d3d12_video_encoder_encode_bitstream struct d3d12_video_encoder *pD3D12Enc = (struct d3d12_video_encoder *) codec; assert(pD3D12Enc); + HRESULT hr = S_OK; debug_printf("[d3d12_video_encoder] d3d12_video_encoder_begin_frame started for fenceValue: %" PRIu64 "\n", pD3D12Enc->m_fenceValue); @@ -1165,6 +1175,14 @@ d3d12_video_encoder_begin_frame(struct pipe_video_codec * codec, goto fail; } + hr = pD3D12Enc->m_spEncodeCommandList->Reset(pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spCommandAllocator.Get()); + if (FAILED(hr)) { + debug_printf( + "[d3d12_video_encoder] d3d12_video_encoder_flush - resetting ID3D12GraphicsCommandList failed with HR %x\n", + hr); + goto fail; + } + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_begin_frame finalized for fenceValue: %" PRIu64 "\n", pD3D12Enc->m_fenceValue); return; @@ -1516,6 +1534,16 @@ d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec, }; pD3D12Enc->m_spEncodeCommandList->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", + d3d12_video_encoder_pool_current_index(pD3D12Enc), + pD3D12Enc->m_spVideoEncoder.Get(), + pD3D12Enc->m_spVideoEncoderHeap.Get(), + inputStreamArguments.pInputFrame, + outputStreamArguments.Bitstream.pBuffer, + inputMetadataCmd.HWLayoutMetadata.pBuffer, + outputMetadataCmd.ResolvedLayoutMetadata.pBuffer, + pD3D12Enc->m_inflightResourcesPool[d3d12_video_encoder_pool_current_index(pD3D12Enc)].m_spCommandAllocator.Get()); + // Transition DPB reference pictures back to COMMON if ((referenceFramesDescriptor.NumTexture2Ds > 0) || (pD3D12Enc->m_upDPBManager->is_current_frame_used_as_reference())) { diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.h b/src/gallium/drivers/d3d12/d3d12_video_enc.h index ef580acfcdd..af212d34122 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.h +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.h @@ -236,7 +236,6 @@ struct d3d12_video_encoder ComPtr m_spVideoEncoder = {}; ComPtr m_spVideoEncoderHeap = {}; ComPtr m_spEncodeCommandQueue = {}; - ComPtr m_spCommandAllocator = {}; ComPtr m_spEncodeCommandList = {}; std::vector m_transitionsBeforeCloseCmdList = {}; @@ -258,6 +257,13 @@ struct d3d12_video_encoder struct D3D12EncodeCapabilities m_currentEncodeCapabilities = { }; struct D3D12EncodeConfiguration m_currentEncodeConfig = { }; + + struct InFlightEncodeResources + { + ComPtr m_spCommandAllocator = {}; + }; + + std::vector m_inflightResourcesPool; }; bool @@ -325,6 +331,7 @@ d3d12_video_encoder_get_current_codec(struct d3d12_video_encoder *pD3D12Enc); bool d3d12_video_encoder_negotiate_requested_features_and_d3d12_driver_caps(struct d3d12_video_encoder *pD3D12Enc, D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT &capEncoderSupportData); bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3D12Enc, D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT &capEncoderSupportData); bool d3d12_video_encoder_check_subregion_mode_support(struct d3d12_video_encoder *pD3D12Enc, D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE requestedSlicesMode); +uint64_t d3d12_video_encoder_pool_current_index(struct d3d12_video_encoder *pD3D12Enc); /// /// d3d12_video_encoder functions ends