d3d12: Apply style format to d3d12_video_dec.cpp

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23969>
This commit is contained in:
Sil Vilerino 2023-07-01 12:26:04 -04:00 committed by Marge Bot
parent af0b4eacab
commit 4b15eaeba8

View file

@ -97,7 +97,7 @@ d3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video
if (!d3d12_video_decoder_check_caps_and_create_decoder(pD3D12Dec->m_pD3D12Screen, pD3D12Dec)) {
debug_printf("[d3d12_video_decoder] d3d12_video_create_decoder - Failure on "
"d3d12_video_decoder_check_caps_and_create_decoder\n");
"d3d12_video_decoder_check_caps_and_create_decoder\n");
goto failed;
}
@ -109,15 +109,15 @@ d3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video
if (!d3d12_video_decoder_create_video_state_buffers(pD3D12Dec->m_pD3D12Screen, pD3D12Dec)) {
debug_printf("[d3d12_video_decoder] d3d12_video_create_decoder - Failure on "
"d3d12_video_decoder_create_video_state_buffers\n");
"d3d12_video_decoder_create_video_state_buffers\n");
goto failed;
}
pD3D12Dec->m_decodeFormatInfo = { pD3D12Dec->m_decodeFormat };
hr = pD3D12Dec->m_pD3D12Screen->dev->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO,
&pD3D12Dec->m_decodeFormatInfo,
sizeof(pD3D12Dec->m_decodeFormatInfo));
if(FAILED(hr)) {
&pD3D12Dec->m_decodeFormatInfo,
sizeof(pD3D12Dec->m_decodeFormatInfo));
if (FAILED(hr)) {
debug_printf("CheckFeatureSupport failed with HR %x\n", hr);
goto failed;
}
@ -148,12 +148,11 @@ d3d12_video_decoder_destroy(struct pipe_video_codec *codec)
// Flush pending work before destroying.
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
uint64_t curBatchFence = pD3D12Dec->m_fenceValue;
if (pD3D12Dec->m_needsGPUFlush)
{
if (pD3D12Dec->m_needsGPUFlush) {
d3d12_video_decoder_flush(codec);
d3d12_video_decoder_sync_completion(codec, curBatchFence, OS_TIMEOUT_INFINITE);
}
//
// Destroys a decoder
// Call destroy_XX for applicable XX nested member types before deallocating
@ -190,24 +189,26 @@ d3d12_video_decoder_begin_frame(struct pipe_video_codec *codec,
///
/// Wait here to make sure the next in flight resource set is empty before using it
///
uint64_t fenceValueToWaitOn = static_cast<uint64_t>(std::max(static_cast<int64_t>(0l), static_cast<int64_t>(pD3D12Dec->m_fenceValue) - static_cast<int64_t>(D3D12_VIDEO_DEC_ASYNC_DEPTH) ));
uint64_t fenceValueToWaitOn = static_cast<uint64_t>(
std::max(static_cast<int64_t>(0l),
static_cast<int64_t>(pD3D12Dec->m_fenceValue) - static_cast<int64_t>(D3D12_VIDEO_DEC_ASYNC_DEPTH)));
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_begin_frame Waiting for completion of in flight resource sets with previous work with fenceValue: %" PRIu64 "\n",
fenceValueToWaitOn);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_begin_frame Waiting for completion of in flight resource "
"sets with previous work with fenceValue: %" PRIu64 "\n",
fenceValueToWaitOn);
ASSERTED bool wait_res = d3d12_video_decoder_sync_completion(codec, fenceValueToWaitOn, OS_TIMEOUT_INFINITE);
assert(wait_res);
HRESULT hr = pD3D12Dec->m_spDecodeCommandList->Reset(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spCommandAllocator.Get());
HRESULT hr = pD3D12Dec->m_spDecodeCommandList->Reset(
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spCommandAllocator.Get());
if (FAILED(hr)) {
debug_printf(
"[d3d12_video_decoder] resetting ID3D12GraphicsCommandList failed with HR %x\n",
hr);
debug_printf("[d3d12_video_decoder] resetting ID3D12GraphicsCommandList failed with HR %x\n", hr);
assert(false);
}
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_begin_frame finalized for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
}
/**
@ -224,7 +225,7 @@ d3d12_video_decoder_decode_bitstream(struct pipe_video_codec *codec,
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
assert(pD3D12Dec);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_decode_bitstream started for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
assert(pD3D12Dec->m_spD3D12VideoDevice);
assert(pD3D12Dec->m_spDecodeCommandQueue);
assert(pD3D12Dec->m_pD3D12Screen);
@ -268,8 +269,8 @@ d3d12_video_decoder_decode_bitstream(struct pipe_video_codec *codec,
// group by start codes and buffers and perform calls for the number of slices
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_decode_bitstream multiple slices on same call detected "
"for fenceValue: %d, breaking down the calls into one per slice\n",
pD3D12Dec->m_fenceValue);
"for fenceValue: %d, breaking down the calls into one per slice\n",
pD3D12Dec->m_fenceValue);
size_t curBufferIdx = 0;
@ -308,14 +309,19 @@ d3d12_video_decoder_decode_bitstream(struct pipe_video_codec *codec,
}
// Bytes of data pre-staged before this decode_frame call
size_t preStagedDataSize = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.size();
size_t preStagedDataSize = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.size();
// Extend the staging buffer size, as decode_frame can be called several times before end_frame
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.resize(preStagedDataSize + totalReceivedBuffersSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.resize(preStagedDataSize + totalReceivedBuffersSize);
// Point newSliceDataPositionDstBase to the end of the pre-staged data in m_stagingDecodeBitstream, where the new
// buffers will be appended
uint8_t *newSliceDataPositionDstBase = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.data() + preStagedDataSize;
uint8_t *newSliceDataPositionDstBase =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.data() +
preStagedDataSize;
// Append new data at the end.
size_t dstOffset = 0u;
@ -325,7 +331,7 @@ d3d12_video_decoder_decode_bitstream(struct pipe_video_codec *codec,
}
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_decode_bitstream finalized for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
}
}
@ -380,7 +386,7 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pD3D12Dec->m_pD3D12Screen;
assert(pD3D12Screen);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame started for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
assert(pD3D12Dec->m_spD3D12VideoDevice);
assert(pD3D12Dec->m_spDecodeCommandQueue);
struct d3d12_video_buffer *pD3D12VideoBuffer = (struct d3d12_video_buffer *) target;
@ -396,61 +402,80 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
///
d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(pD3D12Dec, picture, pD3D12VideoBuffer);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.size() > 0);
assert(
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.size() >
0);
///
/// Prepare Slice control buffers before clearing staging buffer
///
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.size() > 0); // Make sure the staging wasn't cleared yet in end_frame
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.size() > 0); // Make sure the staging wasn't cleared yet in end_frame
d3d12_video_decoder_prepare_dxva_slices_control(pD3D12Dec, picture);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer.size() > 0);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_SliceControlBuffer.size() > 0);
///
/// Upload m_stagingDecodeBitstream to GPU memory now that end_frame is called and clear staging buffer
///
uint64_t sliceDataStagingBufferSize = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.size();
uint8_t *sliceDataStagingBufferPtr = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_stagingDecodeBitstream.data();
uint64_t sliceDataStagingBufferSize =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.size();
uint8_t *sliceDataStagingBufferPtr =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_stagingDecodeBitstream.data();
// Reallocate if necessary to accomodate the current frame bitstream buffer in GPU memory
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferAllocatedSize < sliceDataStagingBufferSize) {
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferAllocatedSize < sliceDataStagingBufferSize) {
if (!d3d12_video_decoder_create_staging_bitstream_buffer(pD3D12Screen, pD3D12Dec, sliceDataStagingBufferSize)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame - Failure on "
"d3d12_video_decoder_create_staging_bitstream_buffer\n");
"d3d12_video_decoder_create_staging_bitstream_buffer\n");
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame failed for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
assert(false);
return;
}
}
// Upload frame bitstream CPU data to ID3D12Resource buffer
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferPayloadSize =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferPayloadSize =
sliceDataStagingBufferSize; // This can be less than m_curFrameCompressedBitstreamBufferAllocatedSize.
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferPayloadSize <=
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferAllocatedSize);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferPayloadSize <=
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferAllocatedSize);
/* One-shot transfer operation with data supplied in a user
* pointer.
*/
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].pPipeCompressedBufferObj =
d3d12_resource_from_resource(&pD3D12Screen->base, pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBuffer.Get());
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].pPipeCompressedBufferObj);
pD3D12Dec->base.context->buffer_subdata(pD3D12Dec->base.context, // context
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].pPipeCompressedBufferObj, // dst buffer
PIPE_MAP_WRITE, // usage PIPE_MAP_x
0, // offset
sizeof(*sliceDataStagingBufferPtr) * sliceDataStagingBufferSize, // size
sliceDataStagingBufferPtr // data
d3d12_resource_from_resource(&pD3D12Screen->base,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBuffer.Get());
assert(
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].pPipeCompressedBufferObj);
pD3D12Dec->base.context->buffer_subdata(
pD3D12Dec->base.context, // context
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.pPipeCompressedBufferObj, // dst buffer
PIPE_MAP_WRITE, // usage PIPE_MAP_x
0, // offset
sizeof(*sliceDataStagingBufferPtr) * sliceDataStagingBufferSize, // size
sliceDataStagingBufferPtr // data
);
// Flush buffer_subdata batch
// before deleting the source CPU buffer below
pD3D12Dec->base.context->flush(pD3D12Dec->base.context,
&pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_pBitstreamUploadGPUCompletionFence,
&pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_pBitstreamUploadGPUCompletionFence,
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_pBitstreamUploadGPUCompletionFence);
assert(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_pBitstreamUploadGPUCompletionFence);
// To be waited on GPU fence before flushing current frame DecodeFrame to GPU
///
@ -467,14 +492,18 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
// Translate input D3D12 structure
D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS d3d12InputArguments = {};
d3d12InputArguments.CompressedBitstream.pBuffer = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBuffer.Get();
d3d12InputArguments.CompressedBitstream.pBuffer =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBuffer.Get();
d3d12InputArguments.CompressedBitstream.Offset = 0u;
ASSERTED constexpr uint64_t d3d12BitstreamOffsetAlignment =
128u; // specified in
// https://docs.microsoft.com/en-us/windows/win32/api/d3d12video/ne-d3d12video-d3d12_video_decode_tier
assert((d3d12InputArguments.CompressedBitstream.Offset == 0) ||
((d3d12InputArguments.CompressedBitstream.Offset % d3d12BitstreamOffsetAlignment) == 0));
d3d12InputArguments.CompressedBitstream.Size = pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferPayloadSize;
((d3d12InputArguments.CompressedBitstream.Offset % d3d12BitstreamOffsetAlignment) == 0));
d3d12InputArguments.CompressedBitstream.Size =
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferPayloadSize;
D3D12_RESOURCE_BARRIER resourceBarrierCommonToDecode[1] = {
CD3DX12_RESOURCE_BARRIER::Transition(d3d12InputArguments.CompressedBitstream.pBuffer,
@ -503,18 +532,18 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
ID3D12Resource *pRefOnlyOutputD3D12Texture;
uint refOnlyOutputD3D12Subresource = 0;
if(!d3d12_video_decoder_prepare_for_decode_frame(pD3D12Dec,
target,
pD3D12VideoBuffer,
&pOutputD3D12Texture, // output
&outputD3D12Subresource, // output
&pRefOnlyOutputD3D12Texture, // output
&refOnlyOutputD3D12Subresource, // output
requestedConversionArguments)) {
if (!d3d12_video_decoder_prepare_for_decode_frame(pD3D12Dec,
target,
pD3D12VideoBuffer,
&pOutputD3D12Texture, // output
&outputD3D12Subresource, // output
&pRefOnlyOutputD3D12Texture, // output
&refOnlyOutputD3D12Subresource, // output
requestedConversionArguments)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame - Failure on "
"d3d12_video_decoder_prepare_for_decode_frame\n");
"d3d12_video_decoder_prepare_for_decode_frame\n");
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame failed for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
assert(false);
return;
}
@ -527,25 +556,34 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
1u; // Only the codec data received from the above layer with picture params
d3d12InputArguments.FrameArguments[d3d12InputArguments.NumFrameArguments - 1] = {
D3D12_VIDEO_DECODE_ARGUMENT_TYPE_PICTURE_PARAMETERS,
static_cast<uint32_t>(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.size()),
static_cast<uint32_t>(
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.size()),
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.data(),
};
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer.size() > 0) {
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_SliceControlBuffer.size() > 0) {
d3d12InputArguments.NumFrameArguments++;
d3d12InputArguments.FrameArguments[d3d12InputArguments.NumFrameArguments - 1] = {
D3D12_VIDEO_DECODE_ARGUMENT_TYPE_SLICE_CONTROL,
static_cast<uint32_t>(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer.size()),
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer.data(),
static_cast<uint32_t>(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_SliceControlBuffer.size()),
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_SliceControlBuffer.data(),
};
}
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled && (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.size() > 0)) {
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled &&
(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.size() > 0)) {
d3d12InputArguments.NumFrameArguments++;
d3d12InputArguments.FrameArguments[d3d12InputArguments.NumFrameArguments - 1] = {
D3D12_VIDEO_DECODE_ARGUMENT_TYPE_INVERSE_QUANTIZATION_MATRIX,
static_cast<uint32_t>(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.size()),
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.data(),
static_cast<uint32_t>(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.size()),
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.data(),
};
}
@ -631,13 +669,16 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
&d3d12InputArguments);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_end_frame finalized for fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
pD3D12Dec->m_fenceValue);
// Save extra references of Decoder, DecoderHeap and DPB allocations in case
// there's a reconfiguration that trigers the construction of new objects
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spDecoder = pD3D12Dec->m_spVideoDecoder;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spDecoderHeap = pD3D12Dec->m_spVideoDecoderHeap;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_References = pD3D12Dec->m_spDPBManager;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spDecoder =
pD3D12Dec->m_spVideoDecoder;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_spDecoderHeap =
pD3D12Dec->m_spVideoDecoderHeap;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_References =
pD3D12Dec->m_spDPBManager;
///
/// Flush work to the GPU
@ -647,13 +688,10 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
// Call to d3d12_video_decoder_flush increases m_FenceValue
uint64_t inflightIndexBeforeFlush = (pD3D12Dec->m_fenceValue - 1u) % D3D12_VIDEO_DEC_ASYNC_DEPTH;
if (pD3D12Dec->m_spDPBManager->is_pipe_buffer_underlying_output_decode_allocation())
{
if (pD3D12Dec->m_spDPBManager->is_pipe_buffer_underlying_output_decode_allocation()) {
// No need to copy, the output surface fence is merely the decode queue fence
*picture->fence = (pipe_fence_handle*) &pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_FenceData;
}
else
{
*picture->fence = (pipe_fence_handle *) &pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_FenceData;
} else {
///
/// If !pD3D12Dec->m_spDPBManager->is_pipe_buffer_underlying_output_decode_allocation()
/// We cannot use the standalone video buffer allocation directly and we must use instead
@ -673,8 +711,7 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
// GPU wait on the graphics context which will do the copy until the decode finishes
pD3D12Screen->cmdqueue->Wait(
pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_FenceData.cmdqueue_fence,
pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_FenceData.value
);
pD3D12Dec->m_inflightResourcesPool[inflightIndexBeforeFlush].m_FenceData.value);
// Copy all format subresources/texture planes
for (PlaneSlice = 0; PlaneSlice < pD3D12Dec->m_decodeFormatInfo.PlaneCount; PlaneSlice++) {
@ -699,18 +736,15 @@ d3d12_video_decoder_end_frame(struct pipe_video_codec *codec,
}
// Flush resource_copy_region batch
// The output surface fence is the graphics queue that will signal after the copy ends
pD3D12Dec->base.context->flush(pD3D12Dec->base.context,
picture->fence,
PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
pD3D12Dec->base.context->flush(pD3D12Dec->base.context, picture->fence, PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
}
}
/**
* Get decoder fence.
*/
int d3d12_video_decoder_get_decoder_fence(struct pipe_video_codec *codec,
struct pipe_fence_handle *fence,
uint64_t timeout)
int
d3d12_video_decoder_get_decoder_fence(struct pipe_video_codec *codec, struct pipe_fence_handle *fence, uint64_t timeout)
{
struct d3d12_fence *fenceValueToWaitOn = (struct d3d12_fence *) fence;
assert(fenceValueToWaitOn);
@ -735,8 +769,8 @@ d3d12_video_decoder_flush(struct pipe_video_codec *codec)
assert(pD3D12Dec->m_spD3D12VideoDevice);
assert(pD3D12Dec->m_spDecodeCommandQueue);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_flush started. Will flush video queue work and CPU wait on "
"fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
"fenceValue: %d\n",
pD3D12Dec->m_fenceValue);
if (!pD3D12Dec->m_needsGPUFlush) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_flush started. Nothing to flush, all up to date.\n");
@ -744,9 +778,9 @@ d3d12_video_decoder_flush(struct pipe_video_codec *codec)
HRESULT hr = pD3D12Dec->m_pD3D12Screen->dev->GetDeviceRemovedReason();
if (hr != S_OK) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_flush"
" - D3D12Device was removed BEFORE commandlist "
"execution with HR %x.\n",
hr);
" - D3D12Device was removed BEFORE commandlist "
"execution with HR %x.\n",
hr);
goto flush_fail;
}
@ -763,7 +797,9 @@ d3d12_video_decoder_flush(struct pipe_video_codec *codec)
}
ID3D12CommandList *ppCommandLists[1] = { pD3D12Dec->m_spDecodeCommandList.Get() };
struct d3d12_fence* pUploadBitstreamFence = d3d12_fence(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_pBitstreamUploadGPUCompletionFence);
struct d3d12_fence *pUploadBitstreamFence =
d3d12_fence(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_pBitstreamUploadGPUCompletionFence);
pD3D12Dec->m_spDecodeCommandQueue->Wait(pUploadBitstreamFence->cmdqueue_fence, pUploadBitstreamFence->value);
pD3D12Dec->m_spDecodeCommandQueue->ExecuteCommandLists(1, ppCommandLists);
pD3D12Dec->m_spDecodeCommandQueue->Signal(pD3D12Dec->m_spFence.Get(), pD3D12Dec->m_fenceValue);
@ -772,19 +808,21 @@ d3d12_video_decoder_flush(struct pipe_video_codec *codec)
hr = pD3D12Dec->m_pD3D12Screen->dev->GetDeviceRemovedReason();
if (hr != S_OK) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_flush"
" - D3D12Device was removed AFTER commandlist "
"execution with HR %x, but wasn't before.\n",
hr);
" - D3D12Device was removed AFTER commandlist "
"execution with HR %x, but wasn't before.\n",
hr);
goto flush_fail;
}
// Set async fence info
memset(&pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData,
0,
sizeof(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData));
0,
sizeof(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData));
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData.value = pD3D12Dec->m_fenceValue;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData.cmdqueue_fence = pD3D12Dec->m_spFence.Get();
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData.value =
pD3D12Dec->m_fenceValue;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_FenceData.cmdqueue_fence =
pD3D12Dec->m_spFence.Get();
pD3D12Dec->m_fenceValue++;
pD3D12Dec->m_needsGPUFlush = false;
@ -807,8 +845,8 @@ d3d12_video_decoder_create_command_objects(const struct d3d12_screen *pD3D12Scre
IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandQueue.GetAddressOf()));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_create_command_objects - Call to CreateCommandQueue "
"failed with HR %x\n",
hr);
"failed with HR %x\n",
hr);
return false;
}
@ -820,36 +858,34 @@ d3d12_video_decoder_create_command_objects(const struct d3d12_screen *pD3D12Scre
return false;
}
for (auto& inputResource : pD3D12Dec->m_inflightResourcesPool)
{
for (auto &inputResource : pD3D12Dec->m_inflightResourcesPool) {
hr = pD3D12Dec->m_pD3D12Screen->dev->CreateCommandAllocator(
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE,
IID_PPV_ARGS(inputResource.m_spCommandAllocator.GetAddressOf()));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_create_command_objects - Call to "
"CreateCommandAllocator failed with HR %x\n",
hr);
"CreateCommandAllocator failed with HR %x\n",
hr);
return false;
}
}
ComPtr<ID3D12Device4> spD3D12Device4;
if (FAILED(pD3D12Dec->m_pD3D12Screen->dev->QueryInterface(
IID_PPV_ARGS(spD3D12Device4.GetAddressOf())))) {
if (FAILED(pD3D12Dec->m_pD3D12Screen->dev->QueryInterface(IID_PPV_ARGS(spD3D12Device4.GetAddressOf())))) {
debug_printf(
"[d3d12_video_decoder] d3d12_video_decoder_create_decoder - D3D12 Device has no ID3D12Device4 support\n");
return false;
}
hr = spD3D12Device4->CreateCommandList1(0,
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE,
D3D12_COMMAND_LIST_FLAG_NONE,
IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandList.GetAddressOf()));
D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE,
D3D12_COMMAND_LIST_FLAG_NONE,
IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandList.GetAddressOf()));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_create_command_objects - Call to CreateCommandList "
"failed with HR %x\n",
hr);
"failed with HR %x\n",
hr);
return false;
}
@ -884,14 +920,14 @@ d3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen *pD3
sizeof(decodeSupport));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_check_caps_and_create_decoder - CheckFeatureSupport "
"failed with HR %x\n",
hr);
"failed with HR %x\n",
hr);
return false;
}
if (!(decodeSupport.SupportFlags & D3D12_VIDEO_DECODE_SUPPORT_FLAG_SUPPORTED)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_check_caps_and_create_decoder - "
"D3D12_VIDEO_DECODE_SUPPORT_FLAG_SUPPORTED was false when checking caps \n");
"D3D12_VIDEO_DECODE_SUPPORT_FLAG_SUPPORTED was false when checking caps \n");
return false;
}
@ -918,8 +954,8 @@ d3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen *pD3
IID_PPV_ARGS(pD3D12Dec->m_spVideoDecoder.GetAddressOf()));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_check_caps_and_create_decoder - CreateVideoDecoder "
"failed with HR %x\n",
hr);
"failed with HR %x\n",
hr);
return false;
}
@ -935,7 +971,7 @@ d3d12_video_decoder_create_video_state_buffers(const struct d3d12_screen *pD3D12
pD3D12Dec,
pD3D12Dec->m_InitialCompBitstreamGPUBufferSize)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_create_video_state_buffers - Failure on "
"d3d12_video_decoder_create_staging_bitstream_buffer\n");
"d3d12_video_decoder_create_staging_bitstream_buffer\n");
return false;
}
@ -949,8 +985,10 @@ d3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen *p
{
assert(pD3D12Dec->m_spD3D12VideoDevice);
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBuffer.Get() != nullptr) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBuffer.Reset();
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBuffer.Get() != nullptr) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBuffer.Reset();
}
auto descHeap = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT, pD3D12Dec->m_NodeMask, pD3D12Dec->m_NodeMask);
@ -961,15 +999,17 @@ d3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen *p
&descResource,
D3D12_RESOURCE_STATE_COMMON,
nullptr,
IID_PPV_ARGS(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBuffer.GetAddressOf()));
IID_PPV_ARGS(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBuffer.GetAddressOf()));
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_create_staging_bitstream_buffer - "
"CreateCommittedResource failed with HR %x\n",
hr);
"CreateCommittedResource failed with HR %x\n",
hr);
return false;
}
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_curFrameCompressedBitstreamBufferAllocatedSize = bufSize;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_curFrameCompressedBitstreamBufferAllocatedSize = bufSize;
return true;
}
@ -983,7 +1023,7 @@ d3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12D
uint32_t *pRefOnlyOutSubresourceIndex,
const d3d12_video_decode_output_conversion_arguments &conversionArgs)
{
if(!d3d12_video_decoder_reconfigure_dpb(pD3D12Dec, pD3D12VideoBuffer, conversionArgs)) {
if (!d3d12_video_decoder_reconfigure_dpb(pD3D12Dec, pD3D12VideoBuffer, conversionArgs)) {
debug_printf("d3d12_video_decoder_reconfigure_dpb failed!\n");
return false;
}
@ -996,14 +1036,14 @@ d3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12D
ppOutTexture2D,
pOutSubresourceIndex);
auto vidBuffer = (struct d3d12_video_buffer *)(pCurrentDecodeTarget);
auto vidBuffer = (struct d3d12_video_buffer *) (pCurrentDecodeTarget);
// If is_pipe_buffer_underlying_output_decode_allocation is enabled,
// we can just use the underlying allocation in pCurrentDecodeTarget
// and avoid an extra copy after decoding the frame.
// If this is the case, we need to handle the residency of this resource
// (if not we're actually creating the resources with CreateCommitedResource with
// residency by default)
if(pD3D12Dec->m_spDPBManager->is_pipe_buffer_underlying_output_decode_allocation()) {
if (pD3D12Dec->m_spDPBManager->is_pipe_buffer_underlying_output_decode_allocation()) {
assert(d3d12_resource_resource(vidBuffer->texture) == *ppOutTexture2D);
// Make it permanently resident for video use
d3d12_promote_to_permanent_residency(pD3D12Dec->m_pD3D12Screen, vidBuffer->texture);
@ -1075,15 +1115,15 @@ d3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12D
case d3d12_video_decode_profile_type_av1:
{
d3d12_video_decoder_prepare_current_frame_references_av1(pD3D12Dec,
pCurrentFrameDPBEntry,
currentFrameDPBEntrySubresource);
pCurrentFrameDPBEntry,
currentFrameDPBEntrySubresource);
} break;
case d3d12_video_decode_profile_type_vp9:
{
d3d12_video_decoder_prepare_current_frame_references_vp9(pD3D12Dec,
pCurrentFrameDPBEntry,
currentFrameDPBEntrySubresource);
pCurrentFrameDPBEntry,
currentFrameDPBEntrySubresource);
} break;
default:
@ -1279,7 +1319,8 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
d3d12_video_decoder_convert_pipe_video_profile_to_profile_type(codec->base.profile);
ID3D12Resource *pPipeD3D12DstResource = d3d12_resource_resource(pD3D12VideoBuffer->texture);
D3D12_RESOURCE_DESC outputResourceDesc = GetDesc(pPipeD3D12DstResource);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled = false;
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled = false;
switch (profileType) {
case d3d12_video_decode_profile_type_h264:
{
@ -1298,9 +1339,10 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
size_t dxvaQMatrixBufferSize = sizeof(DXVA_Qmatrix_H264);
DXVA_Qmatrix_H264 dxvaQmatrixH264 = {};
d3d12_video_decoder_dxva_qmatrix_from_pipe_picparams_h264((pipe_h264_picture_desc *) picture,
dxvaQmatrixH264);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled = true; // We don't have a way of knowing from the pipe params so send always
d3d12_video_decoder_dxva_qmatrix_from_pipe_picparams_h264((pipe_h264_picture_desc *) picture, dxvaQmatrixH264);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled =
true; // We don't have a way of knowing from the pipe params so send always
d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(codec, &dxvaQmatrixH264, dxvaQMatrixBufferSize);
} break;
@ -1309,9 +1351,7 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
size_t dxvaPicParamsBufferSize = sizeof(DXVA_PicParams_HEVC);
pipe_h265_picture_desc *pPicControlHEVC = (pipe_h265_picture_desc *) picture;
DXVA_PicParams_HEVC dxvaPicParamsHEVC =
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_hevc(pD3D12Dec,
codec->base.profile,
pPicControlHEVC);
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_hevc(pD3D12Dec, codec->base.profile, pPicControlHEVC);
d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(codec,
&dxvaPicParamsHEVC,
@ -1319,10 +1359,13 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
size_t dxvaQMatrixBufferSize = sizeof(DXVA_Qmatrix_HEVC);
DXVA_Qmatrix_HEVC dxvaQmatrixHEVC = {};
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled = false;
d3d12_video_decoder_dxva_qmatrix_from_pipe_picparams_hevc((pipe_h265_picture_desc *) picture,
dxvaQmatrixHEVC,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled = false;
d3d12_video_decoder_dxva_qmatrix_from_pipe_picparams_hevc(
(pipe_h265_picture_desc *) picture,
dxvaQmatrixHEVC,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled);
d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(codec, &dxvaQmatrixHEVC, dxvaQMatrixBufferSize);
} break;
case d3d12_video_decode_profile_type_av1:
@ -1331,27 +1374,23 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
pipe_av1_picture_desc *pPicControlAV1 = (pipe_av1_picture_desc *) picture;
DXVA_PicParams_AV1 dxvaPicParamsAV1 =
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_av1(pD3D12Dec->m_fenceValue,
codec->base.profile,
pPicControlAV1);
codec->base.profile,
pPicControlAV1);
d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(codec,
&dxvaPicParamsAV1,
dxvaPicParamsBufferSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled = false;
d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(codec, &dxvaPicParamsAV1, dxvaPicParamsBufferSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled = false;
} break;
case d3d12_video_decode_profile_type_vp9:
{
size_t dxvaPicParamsBufferSize = sizeof(DXVA_PicParams_VP9);
pipe_vp9_picture_desc *pPicControlVP9 = (pipe_vp9_picture_desc *) picture;
DXVA_PicParams_VP9 dxvaPicParamsVP9 =
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_vp9(pD3D12Dec,
codec->base.profile,
pPicControlVP9);
d3d12_video_decoder_dxva_picparams_from_pipe_picparams_vp9(pD3D12Dec, codec->base.profile, pPicControlVP9);
d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(codec,
&dxvaPicParamsVP9,
dxvaPicParamsBufferSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].qp_matrix_frame_argument_enabled = false;
d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(codec, &dxvaPicParamsVP9, dxvaPicParamsBufferSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.qp_matrix_frame_argument_enabled = false;
} break;
default:
{
@ -1363,28 +1402,39 @@ d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(
void
d3d12_video_decoder_prepare_dxva_slices_control(
struct d3d12_video_decoder *pD3D12Dec, // input argument, current decoder
struct pipe_picture_desc *picture
)
struct pipe_picture_desc *picture)
{
d3d12_video_decode_profile_type profileType =
d3d12_video_decoder_convert_pipe_video_profile_to_profile_type(pD3D12Dec->base.profile);
switch (profileType) {
case d3d12_video_decode_profile_type_h264:
{
d3d12_video_decoder_prepare_dxva_slices_control_h264(pD3D12Dec, pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer, (struct pipe_h264_picture_desc*) picture);
d3d12_video_decoder_prepare_dxva_slices_control_h264(
pD3D12Dec,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer,
(struct pipe_h264_picture_desc *) picture);
} break;
case d3d12_video_decode_profile_type_hevc:
{
d3d12_video_decoder_prepare_dxva_slices_control_hevc(pD3D12Dec, pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer, (struct pipe_h265_picture_desc*) picture);
d3d12_video_decoder_prepare_dxva_slices_control_hevc(
pD3D12Dec,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer,
(struct pipe_h265_picture_desc *) picture);
} break;
case d3d12_video_decode_profile_type_av1:
{
d3d12_video_decoder_prepare_dxva_slices_control_av1(pD3D12Dec, pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer, (struct pipe_av1_picture_desc*) picture);
d3d12_video_decoder_prepare_dxva_slices_control_av1(
pD3D12Dec,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer,
(struct pipe_av1_picture_desc *) picture);
} break;
case d3d12_video_decode_profile_type_vp9:
{
d3d12_video_decoder_prepare_dxva_slices_control_vp9(pD3D12Dec, pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer, (struct pipe_vp9_picture_desc*) picture);
d3d12_video_decoder_prepare_dxva_slices_control_vp9(
pD3D12Dec,
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_SliceControlBuffer,
(struct pipe_vp9_picture_desc *) picture);
} break;
default:
@ -1399,12 +1449,18 @@ d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(struct d3d12_video_deco
void *pDXVAStruct,
uint64_t DXVAStructSize)
{
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.capacity() < DXVAStructSize) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.reserve(DXVAStructSize);
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.capacity() < DXVAStructSize) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.reserve(DXVAStructSize);
}
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.resize(DXVAStructSize);
memcpy(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_InverseQuantMatrixBuffer.data(), pDXVAStruct, DXVAStructSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.resize(DXVAStructSize);
memcpy(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_InverseQuantMatrixBuffer.data(),
pDXVAStruct,
DXVAStructSize);
}
void
@ -1412,12 +1468,18 @@ d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(struct d3d12_video_
void *pDXVAStruct,
uint64_t DXVAStructSize)
{
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.capacity() < DXVAStructSize) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.reserve(DXVAStructSize);
if (pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_picParamsBuffer.capacity() < DXVAStructSize) {
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.reserve(
DXVAStructSize);
}
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.resize(DXVAStructSize);
memcpy(pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.data(), pDXVAStruct, DXVAStructSize);
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.resize(
DXVAStructSize);
memcpy(
pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.data(),
pDXVAStruct,
DXVAStructSize);
}
bool
@ -1535,48 +1597,56 @@ d3d12_video_decoder_resolve_profile(d3d12_video_decode_profile_type profileType,
}
bool
d3d12_video_decoder_ensure_fence_finished(struct pipe_video_codec *codec, uint64_t fenceValueToWaitOn, uint64_t timeout_ns)
d3d12_video_decoder_ensure_fence_finished(struct pipe_video_codec *codec,
uint64_t fenceValueToWaitOn,
uint64_t timeout_ns)
{
bool wait_result = true;
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
HRESULT hr = S_OK;
uint64_t completedValue = pD3D12Dec->m_spFence->GetCompletedValue();
bool wait_result = true;
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
HRESULT hr = S_OK;
uint64_t completedValue = pD3D12Dec->m_spFence->GetCompletedValue();
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Waiting for fence (with timeout_ns %" PRIu64 ") to finish with "
"fenceValue: %" PRIu64 " - Current Fence Completed Value %" PRIu64 "\n",
timeout_ns, fenceValueToWaitOn, completedValue);
debug_printf(
"[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Waiting for fence (with timeout_ns %" PRIu64
") to finish with "
"fenceValue: %" PRIu64 " - Current Fence Completed Value %" PRIu64 "\n",
timeout_ns,
fenceValueToWaitOn,
completedValue);
if(completedValue < fenceValueToWaitOn) {
if (completedValue < fenceValueToWaitOn) {
HANDLE event = { };
int event_fd = 0;
event = d3d12_fence_create_event(&event_fd);
HANDLE event = {};
int event_fd = 0;
event = d3d12_fence_create_event(&event_fd);
hr = pD3D12Dec->m_spFence->SetEventOnCompletion(fenceValueToWaitOn, event);
if (FAILED(hr)) {
debug_printf(
"[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - SetEventOnCompletion for fenceValue %" PRIu64 " failed with HR %x\n",
fenceValueToWaitOn, hr);
goto ensure_fence_finished_fail;
}
wait_result = d3d12_fence_wait_event(event, event_fd, timeout_ns);
d3d12_fence_close_event(event, event_fd);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Waiting on fence to be done with "
"fenceValue: %" PRIu64 " - current CompletedValue: %" PRIu64 "\n",
fenceValueToWaitOn,
completedValue);
} else {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Fence already done with "
"fenceValue: %" PRIu64 " - current CompletedValue: %" PRIu64 "\n",
fenceValueToWaitOn,
completedValue);
hr = pD3D12Dec->m_spFence->SetEventOnCompletion(fenceValueToWaitOn, event);
if (FAILED(hr)) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - SetEventOnCompletion for "
"fenceValue %" PRIu64 " failed with HR %x\n",
fenceValueToWaitOn,
hr);
goto ensure_fence_finished_fail;
}
return wait_result;
wait_result = d3d12_fence_wait_event(event, event_fd, timeout_ns);
d3d12_fence_close_event(event, event_fd);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Waiting on fence to be done with "
"fenceValue: %" PRIu64 " - current CompletedValue: %" PRIu64 "\n",
fenceValueToWaitOn,
completedValue);
} else {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_ensure_fence_finished - Fence already done with "
"fenceValue: %" PRIu64 " - current CompletedValue: %" PRIu64 "\n",
fenceValueToWaitOn,
completedValue);
}
return wait_result;
ensure_fence_finished_fail:
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion failed for fenceValue: %" PRIu64 "\n", fenceValueToWaitOn);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion failed for fenceValue: %" PRIu64 "\n",
fenceValueToWaitOn);
assert(false);
return false;
}
@ -1584,51 +1654,61 @@ ensure_fence_finished_fail:
bool
d3d12_video_decoder_sync_completion(struct pipe_video_codec *codec, uint64_t fenceValueToWaitOn, uint64_t timeout_ns)
{
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
assert(pD3D12Dec);
assert(pD3D12Dec->m_spD3D12VideoDevice);
assert(pD3D12Dec->m_spDecodeCommandQueue);
HRESULT hr = S_OK;
struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
assert(pD3D12Dec);
assert(pD3D12Dec->m_spD3D12VideoDevice);
assert(pD3D12Dec->m_spDecodeCommandQueue);
HRESULT hr = S_OK;
ASSERTED bool wait_result = d3d12_video_decoder_ensure_fence_finished(codec, fenceValueToWaitOn, timeout_ns);
assert(wait_result);
ASSERTED bool wait_result = d3d12_video_decoder_ensure_fence_finished(codec, fenceValueToWaitOn, timeout_ns);
assert(wait_result);
// Release references granted on end_frame for this inflight operations
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spDecoder.Reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spDecoderHeap.Reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_References.reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_stagingDecodeBitstream.resize(0);
pipe_resource_reference(&pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].pPipeCompressedBufferObj, NULL);
// Release references granted on end_frame for this inflight operations
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spDecoder.Reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spDecoderHeap.Reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_References.reset();
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_stagingDecodeBitstream.resize(
0);
pipe_resource_reference(
&pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].pPipeCompressedBufferObj,
NULL);
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pD3D12Dec->m_pD3D12Screen;
assert(pD3D12Screen);
struct d3d12_screen *pD3D12Screen = (struct d3d12_screen *) pD3D12Dec->m_pD3D12Screen;
assert(pD3D12Screen);
pD3D12Screen->base.fence_reference(&pD3D12Screen->base, &pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_pBitstreamUploadGPUCompletionFence, NULL);
pD3D12Screen->base.fence_reference(
&pD3D12Screen->base,
&pD3D12Dec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)]
.m_pBitstreamUploadGPUCompletionFence,
NULL);
hr = pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spCommandAllocator->Reset();
if(FAILED(hr)) {
debug_printf("failed with %x.\n", hr);
goto sync_with_token_fail;
}
hr =
pD3D12Dec->m_inflightResourcesPool[fenceValueToWaitOn % D3D12_VIDEO_DEC_ASYNC_DEPTH].m_spCommandAllocator->Reset();
if (FAILED(hr)) {
debug_printf("failed with %x.\n", hr);
goto sync_with_token_fail;
}
// Validate device was not removed
hr = pD3D12Dec->m_pD3D12Screen->dev->GetDeviceRemovedReason();
if (hr != S_OK) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion"
" - D3D12Device was removed AFTER d3d12_video_decoder_ensure_fence_finished "
"execution with HR %x, but wasn't before.\n",
hr);
goto sync_with_token_fail;
}
// Validate device was not removed
hr = pD3D12Dec->m_pD3D12Screen->dev->GetDeviceRemovedReason();
if (hr != S_OK) {
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion"
" - D3D12Device was removed AFTER d3d12_video_decoder_ensure_fence_finished "
"execution with HR %x, but wasn't before.\n",
hr);
goto sync_with_token_fail;
}
debug_printf(
"[d3d12_video_decoder] d3d12_video_decoder_sync_completion - GPU execution finalized for fenceValue: %" PRIu64 "\n",
fenceValueToWaitOn);
debug_printf(
"[d3d12_video_decoder] d3d12_video_decoder_sync_completion - GPU execution finalized for fenceValue: %" PRIu64
"\n",
fenceValueToWaitOn);
return wait_result;
return wait_result;
sync_with_token_fail:
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion failed for fenceValue: %" PRIu64 "\n", fenceValueToWaitOn);
debug_printf("[d3d12_video_decoder] d3d12_video_decoder_sync_completion failed for fenceValue: %" PRIu64 "\n",
fenceValueToWaitOn);
assert(false);
return false;
}