From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id BFCED4B016 for ; Sat, 19 Jul 2025 04:05:42 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id F0A0E68B75A; Sat, 19 Jul 2025 07:05:37 +0300 (EEST) Received: from MEUPR01CU001.outbound.protection.outlook.com (mail-australiasoutheastazolkn19010014.outbound.protection.outlook.com [52.103.73.14]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 6BF6C68A408 for ; Sat, 19 Jul 2025 07:05:31 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LT+Cv7/UWPuHgvsYc62e+lhQlDfzS1QNcb8X8yl01ADlcY3gG+YxAapCf0Aan+RaVlK5ojRlWU0z/hSWp3x4o4c2CTUQCJoT7f267mgWeIGSwLgGEw2+D85XDZUC67rIkL19DqnOiYS3EUh7yeKVNUZ4hxSgiXuCBsE8tpGG9b5yXd14Gxm8/Ofn1utDL+CYCQYOBEWAufnEw81UIXSb+B4bS0eHAHWHYKedeDFUl3cht5Lhtwhlolh+UPR3/p3ek3B33vT0a7HZoePrZd2/c5aidEyArCNTGFfzr8HIuGvacHx+hDGXlvXx9vtGQylahp6vbGeMaxRL4/A0hVRW7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=E8jkB/bjMLIrB0KMNQ7Z1dUDC3m/+9MC4HEXmRs+WN8=; b=tC9LaO0WW92Ls3L1Mf+W7wYR8kdO09K7pWrki+7EoBDV6JgjW1+KB4JNbK/TMoLbii/tWiLIBGGvc/wY07hOmY6ACFn+ThEZT6N07onNhfzzygbXLpWMufQVPMxwOzdzTDMvpYvdmgQ4wUTKushvfHr7wgUaME3rge8oE856aP9lWctgHNhXac/EZ/XPyrKIH/9xg4ODTgUmgw6yXs8zIaWpMr8WIy4NGhHJAhWTl7m36PpMdmyBeh0ggaXvn3uOAN/sY1KOq5fjnH+YwygTmTT6EQdhlUJ2ADTJaOe7NxwnA3nzDItykuI7BiEqf5752lyOIWUfhvfr5S4j24k6zw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E8jkB/bjMLIrB0KMNQ7Z1dUDC3m/+9MC4HEXmRs+WN8=; b=PpFTn4nKGCpQH/2gJXzYfmSy23bULfwU21m3lAegIwnyQxushp7PsaJrJH63m6wxSS2aiL+wdIwYMLai7Fy456yTMuuSeWbtvb/8V4VQFL7QdSCyhrFFpOhvdFZmtzX0KOUP0sulEEljI823daqKWcm+953tCkmVfn/FLXym2SkMuncK9YhoOh/oFqgr/2mAN5ge1wl2u9QvjKZ7Jh4+R/3I7j/SwYAsRd4hMUokvJiAdzvt21l04LGkn01o7pSeTtqUuLj2v95TBs4dsYRFoJxtx4LxaF4bmdC9hXJl7btwH0RP2x/TtlmHk26PwKi3z8HxvL/Z0Ycjz5DSArB7bg== Received: from SYYP282MB1439.AUSP282.PROD.OUTLOOK.COM (2603:10c6:10:7d::7) by SY8P282MB4530.AUSP282.PROD.OUTLOOK.COM (2603:10c6:10:257::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8943.28; Sat, 19 Jul 2025 04:05:26 +0000 Received: from SYYP282MB1439.AUSP282.PROD.OUTLOOK.COM ([fe80::2cd1:7eab:5779:c40e]) by SYYP282MB1439.AUSP282.PROD.OUTLOOK.COM ([fe80::2cd1:7eab:5779:c40e%6]) with mapi id 15.20.8943.028; Sat, 19 Jul 2025 04:05:26 +0000 From: Tong Wu To: FFmpeg development discussions and patches Thread-Topic: [FFmpeg-devel] [PATCH, v6] avcodec/d3d12va_encode: texture array support for HEVC Thread-Index: AQHb9x8HOwczPpf4tU6olX+yvLBAdbQ41lig Date: Sat, 19 Jul 2025 04:05:26 +0000 Message-ID: References: <20250717133023.283-1-Primeadvice@gmail.com> In-Reply-To: <20250717133023.283-1-Primeadvice@gmail.com> Accept-Language: en-US, zh-CN Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-traffictypediagnostic: SYYP282MB1439:EE_|SY8P282MB4530:EE_ x-ms-office365-filtering-correlation-id: 067d4916-2980-4b94-8055-08ddc6797dfc x-microsoft-antispam: BCL:0; ARA:14566002|15080799012|41001999006|461199028|56899033|3412199025|40105399003|440099028|102099032|10035399007|12091999003; x-microsoft-antispam-message-info: =?us-ascii?Q?rV+axWbssbHomG8t513Alo3BORNZG+jFz++CBFhAEn0puNFdTj8p8Fi6Iup6?= =?us-ascii?Q?rNrfkB609HbZTqZVAJhlNHWUOvHuegcDoj6/WiV+vTDfUZYAIZykUsTzhV4p?= =?us-ascii?Q?YHOuoNAfnNvkaQTT9JvpKxODca32N3aUpb3hLjeMY5b0jKNAg545s9nO0oDV?= =?us-ascii?Q?zNXeBBDvruPpi6azf6Vj8tSLgjNoIVDVun3ISkrlZXYf8VWKYZROMzTIyc85?= =?us-ascii?Q?H0k4vHt0R+b/JY9dIblzncg2yU9wbGhlqdUBio9ZYHox+S0GnAILxyKUuT7+?= =?us-ascii?Q?0d7MfyOKDBXEXSID8Vl+ZH1jp8T81WF11X+d+x2XSdQBvQ66MeJwL2wntQmi?= =?us-ascii?Q?vIA9pQY2pSmfUeymXJRuqDHz7bBfMjDn9ltvUUc0tlaKDAN0w31SpjPyel3n?= =?us-ascii?Q?2zB2ihRVziSxfQhXrDNCO7SgklH66NcTVI7pgsM6JxE7o6nLAfN5I14XR2YP?= =?us-ascii?Q?mGf2jDGMpCyC2TupF6oBAkqb6u/4J9aEbNtfV+QvW3N5dHJ8vHv+fTArbamx?= =?us-ascii?Q?GZ2kdMNhzjy21cTsHm0N3BIEadQQEO6qZqentmDKhkSQLiCzro3Xqg8kq3m3?= =?us-ascii?Q?A+72axlCU7VVk0Dw02NurPMlZxoh57vV+WND59DBQKlc9mF2R2DtPAWAER1+?= =?us-ascii?Q?eqm6IPeUgJpewv0nt1TKj6EFwlC5E/QSHnx6oM9oj4Tjdt40+k92z/5TkXAa?= =?us-ascii?Q?2YTwVB5Hqi0GYMohKMtxnL2mp7MffeW4ozz81L1ZFRixjmRrihPiP9yNqqTt?= =?us-ascii?Q?hdNz35bjwOkG/Qw2z4FC/VDRBLHt9bQQZ/lRyMrLs8KqZ7QYChTD+Mcv3H8P?= =?us-ascii?Q?8Xm4Ivls1GT586f4AxeouJUyOkKipFnWib6v8RJ2ilHkzyJan+OnJ5OpAf0w?= =?us-ascii?Q?YIHW+n3y+mTZmKtjYko2TvZ1RofYBeaFqxEVv1DTvgeN0w7uZl725JJp4ZCe?= =?us-ascii?Q?jOZejuoIxxhIn8xL8PyGaVPw0ERoGY/92K+8476aNWi6w1Q/ylMsNSDwjIcW?= =?us-ascii?Q?zG2rYGCRrfKqJx/xrQud1+dfedsYRNRcE2dDBFXgTNHdBT9BowbTDbkfwNU7?= =?us-ascii?Q?RnDZo59mZmJPJY45f46fdgSZjEhCAwyzGeqTco1nIEF5qi2VHD9t0Or2+3t6?= =?us-ascii?Q?5SPrL2plrmZbwvFp74baZ2A/9hk0/PAfZP0FRONNQjZmOtsjRJN+GTI=3D?= x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?C93fIiHQwibHZqFc7kYEWSEVYfP1Gn560CkAwrHVfqQA1vTcsfxgquLErLQI?= =?us-ascii?Q?BdhMHpbXp605QcjqvbCygad5FhseuH45+4f9dn1Zu++i06vAaR9bvaScVJbN?= =?us-ascii?Q?QfOkl/0GGZ3FltB9CWeAqcpbGHdRmRaayIL7lrk9XyNxSupgOrhqAR6uN0Bc?= =?us-ascii?Q?m53mtmoxqeZ+9UD4vbEZIaLhpMfYZm+KF1jl7NvSjzDfmDRhgUesNNFrwCFO?= =?us-ascii?Q?ZInTc5Z/t68lnFBGPuds/Swyt67j2okARSfrG5U35Bw1gxNTRy1y+XiTpZzQ?= =?us-ascii?Q?fwTrS/HpG4G/7biUdJ8zj0lJHX/sX+QnSLSnXhLaTaVmmDGAvKVR0epFIklI?= =?us-ascii?Q?69BawROQl8tu6H3Ux5XH0m52qB1JM+EIoUU2aF99MGNsO5XxtwwDyuK/V4ed?= =?us-ascii?Q?29rIM4njuZ9OH3kXbdGUX1olHZdmyGxuubnpXGkhe0itOrAVUfk5WiniMjXo?= =?us-ascii?Q?ZY0j2KsrI6lkMWGIBPjUkG4gWLDdCD1aEuQSQXclCaBibpY5BmWXDqZ29NCp?= =?us-ascii?Q?silKrtcSjICXxBSPLPEWnUlQbEHP55FxNl0az0EtFDSEV8PPQyoxnTveZhBl?= =?us-ascii?Q?gbCkd1pHZGeX32xDP/lRie4I54RxSoOWVeVNYHOOkABXZDSnggOpBwd7yZAs?= =?us-ascii?Q?2LzvWgOkS7wA35YFNiyyULxCzZyvJP0Nw+xFK/A0/JFJyRLylHdL0T22HPz0?= =?us-ascii?Q?h4xvLlu+U1xh8JsCn/4PUo3FLBrKrM40vEnR314sloweiHU8K3Gr1XkfW+wy?= =?us-ascii?Q?NIoqqk8bvqnCRnfwxIePzTXbQooYamoDPjKtw26vEjFLajbA8FFxkJLdqePb?= =?us-ascii?Q?eCW6bNXkeuv+IwxjbQpl5VJYLmu8hIz1uw7lJre1qozFmVoFXGJj8ZUrAQFz?= =?us-ascii?Q?I6yoQe8kV8J6mT4qdDH5nnL0xlIj4+bQ9I3wzdf9N43fiRlX60LE3qN/LRHZ?= =?us-ascii?Q?ICS6/z3GFc4juBiBp1LHLuzooqSuCU72lj/ztHvOLY/jBsuOaP6wFQj+neI0?= =?us-ascii?Q?leCVZ5Z83loCpoqeLJ9OBTPbKwNy4WuKGM4MheXoxgN2eMAFLen8kKlZDCZC?= =?us-ascii?Q?96e/Nxtw84WonhsNhmf6PdqiMC7gsgOgK7oXRGaKq3DaYI1k91EvF63f2tCK?= =?us-ascii?Q?4sgxRz/R1cUxbJA8D9Vtty4eN53tnydSVxRORdNyVCBEcsFLAet7jiOnJzYh?= =?us-ascii?Q?3nf4oeNpVDnpfKsG+UKlr0Vnt2VhvDMMV3SJ0awtO1K6/nWLwU8HbZ7L7f0?= =?us-ascii?Q?=3D?= MIME-Version: 1.0 X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: SYYP282MB1439.AUSP282.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 067d4916-2980-4b94-8055-08ddc6797dfc X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Jul 2025 04:05:26.3026 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SY8P282MB4530 Subject: Re: [FFmpeg-devel] [PATCH, v6] avcodec/d3d12va_encode: texture array support for HEVC X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Araz Iusubov Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Araz Iusubov: > From: ffmpeg-devel On Behalf Of Araz > Iusubov > Sent: Thursday, July 17, 2025 9:30 PM > To: ffmpeg-devel@ffmpeg.org > Cc: Araz Iusubov > Subject: [FFmpeg-devel] [PATCH, v6] avcodec/d3d12va_encode: texture array > support for HEVC > > This patch adds support for the texture array feature used by AMD boards in the > D3D12 HEVC encoder. > In texture array mode, a single texture array is shared for all reference and > reconstructed pictures using different subresources. > The implementation ensures compatibility and has been successfully tested on > AMD, Intel, and NVIDIA GPUs. > > v2 updates: > 1. The reference to MaxL1ReferencesForB for the H.264 codec was updated to > use the corresponding H.264 field instead of the HEVC one. > 2. Max_subresource_array_size calculation was adjusted by removing the > D3D12VA_VIDEO_ENC_ASYNC_DEPTH offset. > > v3 updates: > 1. Fixed a type mismatch by explicitly casting AVD3D12VAFrame* to > (uint8_t*) when assigning to data[0]. > 2. Adjusted logging format specifier for HRESULT to use `%lx`. > > v4 updates: > 1. Moved texture array management to hwcontext_d3d12va for proper > abstraction. > 2. Added `texture_array` and `texture_array_size` fields to > AVD3D12VAFramesContext. > 3. Implemented shared texture array allocation during `av_hwframe_ctx_init`. > 4. Frames now receive unique subresource indices via > `d3d12va_pool_alloc_texture_array`. > 5. Removed `d3d12va_create_texture_array`, allocation is now handled entirely > within hwcontext. > 6. Encoder now uses subresource indices provided by hwcontext instead of > managing them manually. > > v5 updates: > No changes, resubmitted as v4 was missed by patchwork. > > v6 updates: > 1. Minor cosmetic fixes according to review of v5 2. Bumped lavu version to > 60.5.100 and updated APIchanges > > --- > doc/APIchanges | 4 + > libavcodec/d3d12va_encode.c | 184 +++++++++++++++++++++++-------- > libavcodec/d3d12va_encode.h | 12 ++ > libavcodec/d3d12va_encode_hevc.c | 5 +- > libavutil/hwcontext_d3d12va.c | 65 ++++++++++- > libavutil/hwcontext_d3d12va.h | 18 +++ > libavutil/version.h | 4 +- > 7 files changed, 240 insertions(+), 52 deletions(-) > > diff --git a/doc/APIchanges b/doc/APIchanges index d6e38245f8..eab06cd251 > 100644 > --- a/doc/APIchanges > +++ b/doc/APIchanges > @@ -2,6 +2,10 @@ The last version increases of all libraries were on 2025-03-28 > > API changes, most recent first: > > +2025-07-xx - xxxxxxxxxx - lavu 60.5.100 - hwcontext_d3d12va.h > + Add support for texture array mode AVD3D12VAFrame.subresource_index, > + AVD3D12VAFramesContext.texture_array and texture_array_size > + > 2025-07-xx - xxxxxxxxxd - lavfi 11.2.100 - avfilter.h > Add AVFilterGraph->max_buffered_frames. > > diff --git a/libavcodec/d3d12va_encode.c b/libavcodec/d3d12va_encode.c index > e24a5b8d24..1f202f512c 100644 > --- a/libavcodec/d3d12va_encode.c > +++ b/libavcodec/d3d12va_encode.c > @@ -191,7 +191,8 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > FFHWBaseEncodeContext *base_ctx = avctx->priv_data; > D3D12VAEncodeContext *ctx = avctx->priv_data; > D3D12VAEncodePicture *pic = base_pic->priv; > - AVD3D12VAFramesContext *frames_hwctx = base_ctx->input_frames- > >hwctx; > + AVD3D12VAFramesContext *frames_hwctx_input = base_ctx- > >input_frames->hwctx; > + AVD3D12VAFramesContext *frames_hwctx_recon = base_ctx- > >recon_frames->hwctx; > int err, i, j; > HRESULT hr; > char data[MAX_PARAM_BUFFER_SIZE]; > @@ -221,7 +222,7 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > D3D12_VIDEO_ENCODER_RESOLVE_METADATA_INPUT_ARGUMENTS > input_metadata = { > .EncoderCodec = ctx->codec->d3d12_codec, > .EncoderProfile = ctx->profile->d3d12_profile, > - .EncoderInputFormat = frames_hwctx->format, > + .EncoderInputFormat = frames_hwctx_input->format, > .EncodedPictureEffectiveResolution = ctx->resolution, > }; > > @@ -268,6 +269,8 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > av_log(avctx, AV_LOG_DEBUG, "Recon surface is %p.\n", > pic->recon_surface->texture); > > + pic->subresource_index = ctx->is_texture_array ? > + pic->recon_surface->subresource_index : 0; > + > pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool); > if (!pic->output_buffer_ref) { > err = AVERROR(ENOMEM); > @@ -325,11 +328,26 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > goto fail; > } > > + if (ctx->is_texture_array) { > + d3d12_refs.pSubresources = av_calloc(d3d12_refs.NumTexture2Ds, > + sizeof(*d3d12_refs.pSubresources)); > + if (!d3d12_refs.pSubresources) { > + err = AVERROR(ENOMEM); > + goto fail; > + } > + } > + > i = 0; > - for (j = 0; j < base_pic->nb_refs[0]; j++) > - d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture *)base_pic- > >refs[0][j]->priv)->recon_surface->texture; > - for (j = 0; j < base_pic->nb_refs[1]; j++) > - d3d12_refs.ppTexture2Ds[i++] = ((D3D12VAEncodePicture *)base_pic- > >refs[1][j]->priv)->recon_surface->texture; > + for (j = 0; j < base_pic->nb_refs[0]; j++) { > + d3d12_refs.ppTexture2Ds[i] = ((D3D12VAEncodePicture *)base_pic- > >refs[0][j]->priv)->recon_surface->texture; > + d3d12_refs.pSubresources[i] = ctx->is_texture_array ? > ((D3D12VAEncodePicture *)base_pic->refs[0][j]->priv)->subresource_index : 0; > + i++; > + } > + for (j = 0; j < base_pic->nb_refs[1]; j++) { > + d3d12_refs.ppTexture2Ds[i] = ((D3D12VAEncodePicture *)base_pic- > >refs[1][j]->priv)->recon_surface->texture; > + d3d12_refs.pSubresources[i] = ctx->is_texture_array ? > ((D3D12VAEncodePicture *)base_pic->refs[1][j]->priv)->subresource_index : 0; > + i++; > + } > } > > input_args.PictureControlDesc.IntraRefreshFrameIndex = 0; @@ -343,7 > +361,7 @@ static int d3d12va_encode_issue(AVCodecContext *avctx, > output_args.Bitstream.pBuffer = pic->output_buffer; > output_args.Bitstream.FrameStartOffset = pic- > >aligned_header_size; > output_args.ReconstructedPicture.pReconstructedPicture = pic- > >recon_surface->texture; > - output_args.ReconstructedPicture.ReconstructedPictureSubresource = 0; > + output_args.ReconstructedPicture.ReconstructedPictureSubresource = > + ctx->is_texture_array ? pic->subresource_index : 0; > output_args.EncoderOutputMetadata.pBuffer = pic- > >encoded_metadata; > output_args.EncoderOutputMetadata.Offset = 0; > > @@ -369,52 +387,99 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > goto fail; > } > > -#define TRANSITION_BARRIER(res, before, after) \ > +#define TRANSITION_BARRIER(res, subres, before, after) \ > (D3D12_RESOURCE_BARRIER) { \ > .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, \ > .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, \ > .Transition = { \ > .pResource = res, \ > - .Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, \ > + .Subresource = subres, \ > .StateBefore = before, \ > .StateAfter = after, \ > }, \ > } > > barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_COMMON, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ); > barriers[1] = TRANSITION_BARRIER(pic->output_buffer, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_COMMON, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > - barriers[2] = TRANSITION_BARRIER(pic->recon_surface->texture, > - D3D12_RESOURCE_STATE_COMMON, > - D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > - barriers[3] = TRANSITION_BARRIER(pic->encoded_metadata, > + barriers[2] = TRANSITION_BARRIER(pic->encoded_metadata, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_COMMON, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > - barriers[4] = TRANSITION_BARRIER(pic->resolved_metadata, > + barriers[3] = TRANSITION_BARRIER(pic->resolved_metadata, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_COMMON, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > > - ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 5, barriers); > + ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, > + barriers); > > - if (d3d12_refs.NumTexture2Ds) { > - D3D12_RESOURCE_BARRIER refs_barriers[3]; > - > - for (i = 0; i < d3d12_refs.NumTexture2Ds; i++) > - refs_barriers[i] = TRANSITION_BARRIER(d3d12_refs.ppTexture2Ds[i], > - D3D12_RESOURCE_STATE_COMMON, > - D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ); > - > - ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, > d3d12_refs.NumTexture2Ds, > - refs_barriers); > + //set transit barriers for reference pic and recon pic > + int barriers_ref_index = 0; > + D3D12_RESOURCE_BARRIER *barriers_ref = NULL; > + if (ctx->is_texture_array) { > + barriers_ref = av_calloc(frames_hwctx_recon->texture_array_size * ctx- > >plane_count, > + sizeof(D3D12_RESOURCE_BARRIER)); > + } else { > + barriers_ref = > av_calloc(MAX_DPB_SIZE,sizeof(D3D12_RESOURCE_BARRIER)); > + } > + > + if (ctx->is_texture_array) { > + // In Texture array mode, the D3D12 uses the same texture array > (resource)for all > + // the reference pics in ppTexture2Ds and also for the > pReconstructedPicture, > + // just different subresources. > + D3D12_RESOURCE_DESC references_tex_array_desc = { 0 }; > + > + pic->recon_surface->texture->lpVtbl->GetDesc(pic->recon_surface->textu > + re, &references_tex_array_desc); > + > + for (uint32_t reference_subresource = 0; reference_subresource < > references_tex_array_desc.DepthOrArraySize; > + reference_subresource++) { > + > + //D3D12 DecomposeSubresource > + uint32_t mip_slice, plane_slice, array_slice, array_size; > + array_size = references_tex_array_desc.DepthOrArraySize; > + mip_slice = reference_subresource % > references_tex_array_desc.MipLevels; > + array_slice = (reference_subresource / > + references_tex_array_desc.MipLevels) % array_size; > + > + for (plane_slice = 0; plane_slice < ctx->plane_count; plane_slice++) { > + //Calculate the subresource index > + uint32_t planeOutputSubresource = mip_slice + array_slice * > references_tex_array_desc.MipLevels + > + plane_slice * references_tex_array_desc.MipLevels * > array_size; > + if (reference_subresource == pic->subresource_index) { > + barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic- > >recon_surface->texture, planeOutputSubresource, > + D3D12_RESOURCE_STATE_COMMON, > + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > + } else { > + barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic- > >recon_surface->texture, planeOutputSubresource, > + D3D12_RESOURCE_STATE_COMMON, > + D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ); > + } > + } > + } > + } else { > + barriers_ref[barriers_ref_index++] = TRANSITION_BARRIER(pic- > >recon_surface->texture, > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > + D3D12_RESOURCE_STATE_COMMON, > + > + D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE); > + > + if (d3d12_refs.NumTexture2Ds) { > + for (i = 0; i < d3d12_refs.NumTexture2Ds; i++) > + barriers_ref[barriers_ref_index++] = > TRANSITION_BARRIER(d3d12_refs.ppTexture2Ds[i], > + > D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > + D3D12_RESOURCE_STATE_COMMON, > + > D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ); > + } > } > + ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, > + barriers_ref_index, barriers_ref); > > ID3D12VideoEncodeCommandList2_EncodeFrame(cmd_list, ctx->encoder, ctx- > >encoder_heap, > &input_args, &output_args); > > barriers[3] = TRANSITION_BARRIER(pic->encoded_metadata, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ); > > @@ -422,35 +487,35 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > > > ID3D12VideoEncodeCommandList2_ResolveEncoderOutputMetadata(cmd_list, > &input_metadata, &output_metadata); > > - if (d3d12_refs.NumTexture2Ds) { > - D3D12_RESOURCE_BARRIER refs_barriers[3]; > - > - for (i = 0; i < d3d12_refs.NumTexture2Ds; i++) > - refs_barriers[i] = TRANSITION_BARRIER(d3d12_refs.ppTexture2Ds[i], > - D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ, > - D3D12_RESOURCE_STATE_COMMON); > - > - ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, > d3d12_refs.NumTexture2Ds, > - refs_barriers); > + //swap the barriers_ref transition state > + if (barriers_ref_index > 0) { > + for (i = 0; i < barriers_ref_index; i++) { > + D3D12_RESOURCE_STATES temp_statue = > barriers_ref[i].Transition.StateBefore; > + barriers_ref[i].Transition.StateBefore = > barriers_ref[i].Transition.StateAfter; > + barriers_ref[i].Transition.StateAfter = temp_statue; > + } > + ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, > barriers_ref_index, > + barriers_ref); > } > > barriers[0] = TRANSITION_BARRIER(pic->input_surface->texture, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ, > D3D12_RESOURCE_STATE_COMMON); > barriers[1] = TRANSITION_BARRIER(pic->output_buffer, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, > D3D12_RESOURCE_STATE_COMMON); > - barriers[2] = TRANSITION_BARRIER(pic->recon_surface->texture, > - D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, > - D3D12_RESOURCE_STATE_COMMON); > - barriers[3] = TRANSITION_BARRIER(pic->encoded_metadata, > + barriers[2] = TRANSITION_BARRIER(pic->encoded_metadata, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ, > D3D12_RESOURCE_STATE_COMMON); > - barriers[4] = TRANSITION_BARRIER(pic->resolved_metadata, > + barriers[3] = TRANSITION_BARRIER(pic->resolved_metadata, > + > + D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, > D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE, > D3D12_RESOURCE_STATE_COMMON); > > - ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 5, barriers); > + ID3D12VideoEncodeCommandList2_ResourceBarrier(cmd_list, 4, > + barriers); > > hr = ID3D12VideoEncodeCommandList2_Close(cmd_list); > if (FAILED(hr)) { > @@ -489,6 +554,14 @@ static int d3d12va_encode_issue(AVCodecContext > *avctx, > if (d3d12_refs.ppTexture2Ds) > av_freep(&d3d12_refs.ppTexture2Ds); > > + if (ctx->is_texture_array) { > + if (d3d12_refs.pSubresources) > + av_freep(&d3d12_refs.pSubresources); > + } > + > + if (barriers_ref) > + av_freep(&barriers_ref); > + > return 0; > > fail: > @@ -498,6 +571,14 @@ fail: > if (d3d12_refs.ppTexture2Ds) > av_freep(&d3d12_refs.ppTexture2Ds); > > + if (ctx->is_texture_array) { > + if (d3d12_refs.pSubresources) > + av_freep(&d3d12_refs.pSubresources); > + } > + > + if (barriers_ref) > + av_freep(&barriers_ref); > + > if (ctx->codec->free_picture_params) > ctx->codec->free_picture_params(pic); > > @@ -1341,6 +1422,7 @@ fail: > static int d3d12va_encode_create_recon_frames(AVCodecContext *avctx) { > FFHWBaseEncodeContext *base_ctx = avctx->priv_data; > + D3D12VAEncodeContext *ctx = avctx->priv_data; > AVD3D12VAFramesContext *hwctx; > enum AVPixelFormat recon_format; > int err; > @@ -1364,6 +1446,8 @@ static int > d3d12va_encode_create_recon_frames(AVCodecContext *avctx) > hwctx->flags = D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY > | > D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; > > + hwctx->texture_array_size = ctx->is_texture_array ? MAX_DPB_SIZE + > + 1 : 0; > + > err = av_hwframe_ctx_init(base_ctx->recon_frames_ref); > if (err < 0) { > av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed " > @@ -1396,6 +1480,7 @@ int ff_d3d12va_encode_init(AVCodecContext *avctx) > FFHWBaseEncodeContext *base_ctx = avctx->priv_data; > D3D12VAEncodeContext *ctx = avctx->priv_data; > D3D12_FEATURE_DATA_VIDEO_FEATURE_AREA_SUPPORT support = { 0 }; > + D3D12_FEATURE_DATA_FORMAT_INFO format_info = {0}; > int err; > HRESULT hr; > > @@ -1431,6 +1516,15 @@ int ff_d3d12va_encode_init(AVCodecContext *avctx) > goto fail; > } > > + format_info.Format = ((AVD3D12VAFramesContext*)base_ctx->input_frames- > >hwctx)->format; > + if (FAILED(ID3D12VideoDevice_CheckFeatureSupport(ctx->hwctx->device, > D3D12_FEATURE_FORMAT_INFO, > + &format_info, sizeof(format_info)))) { > + av_log(avctx, AV_LOG_ERROR, "Failed to query format plane count: > 0x%x\n", hr); > + err = AVERROR_EXTERNAL; > + goto fail; > + } > + ctx->plane_count = format_info.PlaneCount; > + > err = d3d12va_encode_set_profile(avctx); > if (err < 0) > goto fail; > @@ -1458,10 +1552,6 @@ int ff_d3d12va_encode_init(AVCodecContext *avctx) > if (err < 0) > goto fail; > > - err = d3d12va_encode_create_recon_frames(avctx); > - if (err < 0) > - goto fail; > - > err = d3d12va_encode_prepare_output_buffers(avctx); > if (err < 0) > goto fail; > @@ -1487,6 +1577,10 @@ int ff_d3d12va_encode_init(AVCodecContext *avctx) > goto fail; > } > > + err = d3d12va_encode_create_recon_frames(avctx); > + if (err < 0) > + goto fail; > + > base_ctx->output_delay = base_ctx->b_per_p; > base_ctx->decode_delay = base_ctx->max_b_depth; > > diff --git a/libavcodec/d3d12va_encode.h b/libavcodec/d3d12va_encode.h index > 3b0b8153d5..c8e64ddffd 100644 > --- a/libavcodec/d3d12va_encode.h > +++ b/libavcodec/d3d12va_encode.h > @@ -52,6 +52,8 @@ typedef struct D3D12VAEncodePicture { > ID3D12Resource *encoded_metadata; > ID3D12Resource *resolved_metadata; > > + int subresource_index; > + > D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA pic_ctl; > > int fence_value; > @@ -189,6 +191,16 @@ typedef struct D3D12VAEncodeContext { > */ > AVBufferPool *output_buffer_pool; > > + /** > + * Flag indicates if the HW is texture array mode. > + */ > + int is_texture_array; > + > + /** > + * The number of planes in the input DXGI FORMAT . > + */ > + int plane_count; > + > /** > * D3D12 video encoder. > */ > diff --git a/libavcodec/d3d12va_encode_hevc.c > b/libavcodec/d3d12va_encode_hevc.c > index 938ba01f54..7e1d973f7e 100644 > --- a/libavcodec/d3d12va_encode_hevc.c > +++ b/libavcodec/d3d12va_encode_hevc.c > @@ -280,9 +280,8 @@ static int > d3d12va_encode_hevc_init_sequence_params(AVCodecContext *avctx) > } > > if (support.SupportFlags & > D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIR > E_TEXTURE_ARRAYS) { > - av_log(avctx, AV_LOG_ERROR, "D3D12 video encode on this device requires > texture array support, " > - "but it's not implemented.\n"); > - return AVERROR_PATCHWELCOME; > + ctx->is_texture_array = 1; > + av_log(avctx, AV_LOG_DEBUG, "D3D12 video encode on this device > + uses texture array mode.\n"); > } > > desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format); > diff --git a/libavutil/hwcontext_d3d12va.c b/libavutil/hwcontext_d3d12va.c index > 6507cf69c1..05418c9d94 100644 > --- a/libavutil/hwcontext_d3d12va.c > +++ b/libavutil/hwcontext_d3d12va.c > @@ -49,6 +49,7 @@ typedef struct D3D12VAFramesContext { > ID3D12GraphicsCommandList *command_list; > AVD3D12VASyncContext sync_ctx; > UINT luma_component_size; > + int nb_surfaces_used; > } D3D12VAFramesContext; > > typedef struct D3D12VADevicePriv { > @@ -174,7 +175,8 @@ fail: > > static void d3d12va_frames_uninit(AVHWFramesContext *ctx) { > - D3D12VAFramesContext *s = ctx->hwctx; > + D3D12VAFramesContext *s = ctx->hwctx; > + AVD3D12VAFramesContext *hwctx = ctx->hwctx; > > D3D12_OBJECT_RELEASE(s->sync_ctx.fence); > if (s->sync_ctx.event) > @@ -185,6 +187,11 @@ static void > d3d12va_frames_uninit(AVHWFramesContext *ctx) > D3D12_OBJECT_RELEASE(s->command_allocator); > D3D12_OBJECT_RELEASE(s->command_list); > D3D12_OBJECT_RELEASE(s->command_queue); > + > + if (hwctx->texture_array) { > + D3D12_OBJECT_RELEASE(hwctx->texture_array); > + hwctx->texture_array = NULL; > + } > } > > static int d3d12va_frames_get_constraints(AVHWDeviceContext *ctx, const void > *hwconfig, AVHWFramesConstraints *constraints) @@ -228,6 +235,28 @@ > static void free_texture(void *opaque, uint8_t *data) > av_freep(&data); > } > > +static AVBufferRef *d3d12va_pool_alloc_texture_array(AVHWFramesContext > +*ctx) { > + AVD3D12VAFrame *desc = av_mallocz(sizeof(*desc)); > + D3D12VAFramesContext *s = ctx->hwctx; > + AVD3D12VAFramesContext *hwctx = ctx->hwctx; > + AVBufferRef *buf; > + > + // In Texture array mode, the D3D12 uses the same texture address for all the > pictures, > + //just different subresources. > + desc->subresource_index = s->nb_surfaces_used; > + desc->texture = hwctx->texture_array; > + > + buf = av_buffer_create((uint8_t *)desc, sizeof(*desc), NULL, NULL, > + 0); > + > + if (!buf) { > + av_free(desc); > + return NULL; > + } > + s->nb_surfaces_used++; > + return buf; > +} > + > static AVBufferRef *d3d12va_pool_alloc(void *opaque, size_t size) { > AVHWFramesContext *ctx = (AVHWFramesContext *)opaque; > @@ -236,6 +265,11 @@ static AVBufferRef *d3d12va_pool_alloc(void *opaque, > size_t size) > > AVBufferRef *buf; > AVD3D12VAFrame *frame; > + > + //For texture array mode, no need to create texture. > + if (hwctx->texture_array_size > 0) > + return d3d12va_pool_alloc_texture_array(ctx); > + > D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; > D3D12_RESOURCE_DESC desc = { > .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D, > @@ -280,7 +314,9 @@ fail: > > static int d3d12va_frames_init(AVHWFramesContext *ctx) { > - AVD3D12VAFramesContext *hwctx = ctx->hwctx; > + AVD3D12VAFramesContext *hwctx = ctx->hwctx; > + AVD3D12VADeviceContext *device_hwctx = ctx->device_ctx->hwctx; > + > int i; > > for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) { @@ -298,6 +334,31 > @@ static int d3d12va_frames_init(AVHWFramesContext *ctx) > return AVERROR(EINVAL); > } > > + //For texture array mode, create texture array resource in the init stage. > + //This texture array will be used for all the pictures,but with different > subresources. > + if (hwctx->texture_array_size > 0) { > + D3D12_HEAP_PROPERTIES props = { .Type = D3D12_HEAP_TYPE_DEFAULT > + }; > + > + D3D12_RESOURCE_DESC desc = { > + .Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D, > + .Alignment = 0, > + .Width = ctx->width, > + .Height = ctx->height, > + .DepthOrArraySize = hwctx->texture_array_size, > + .MipLevels = 1, > + .Format = hwctx->format, > + .SampleDesc = {.Count = 1, .Quality = 0 }, > + .Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, > + .Flags = hwctx->flags, > + }; > + > + if (FAILED(ID3D12Device_CreateCommittedResource(device_hwctx- > >device, &props, D3D12_HEAP_FLAG_NONE, &desc, > + D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, > (void **)&hwctx->texture_array))) { > + av_log(ctx, AV_LOG_ERROR, "Could not create the texture\n"); > + return AVERROR(EINVAL); > + } > + } > + > ffhwframesctx(ctx)->pool_internal = > av_buffer_pool_init2(sizeof(AVD3D12VAFrame), > ctx, d3d12va_pool_alloc, NULL); > > diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h > index 212a6a6146..d48d847d11 100644 > --- a/libavutil/hwcontext_d3d12va.h > +++ b/libavutil/hwcontext_d3d12va.h > @@ -111,6 +111,11 @@ typedef struct AVD3D12VAFrame { > */ > ID3D12Resource *texture; > > + /** > + * In texture array mode, the index of subresource > + */ > + int subresource_index; > + > /** > * The sync context for the texture > * > @@ -137,6 +142,19 @@ typedef struct AVD3D12VAFramesContext { > * @see https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne- > d3d12-d3d12_resource_flags > */ > D3D12_RESOURCE_FLAGS flags; > + > + /** > + * In texture array mode, the D3D12 uses the same the same texture array > (resource)for all > + * pictures. > + */ > + ID3D12Resource *texture_array; > + > + /** > + * In texture array mode, the D3D12 uses the same texture array (resource)for > all > + * pictures, but different subresources to represent each picture. > + * This is the size of the texture array (in number of subresources). > + */ > + int texture_array_size; > } AVD3D12VAFramesContext; > > #endif /* AVUTIL_HWCONTEXT_D3D12VA_H */ diff --git a/libavutil/version.h > b/libavutil/version.h index 2c0aa3e35e..29cd31e229 100644 > --- a/libavutil/version.h > +++ b/libavutil/version.h > @@ -79,8 +79,8 @@ > */ > > #define LIBAVUTIL_VERSION_MAJOR 60 > -#define LIBAVUTIL_VERSION_MINOR 4 > -#define LIBAVUTIL_VERSION_MICRO 101 > +#define LIBAVUTIL_VERSION_MINOR 5 > +#define LIBAVUTIL_VERSION_MICRO 100 > > #define LIBAVUTIL_VERSION_INT > AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ > LIBAVUTIL_VERSION_MINOR, \ > -- > 2.45.2.windows.1 > LGTM, will apply _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".