xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/d3d12/d3d12_video_dec.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © Microsoft Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef D3D12_VIDEO_DEC_H
25 #define D3D12_VIDEO_DEC_H
26 
27 #include "d3d12_video_types.h"
28 #include "d3d12_video_dec_references_mgr.h"
29 
30 ///
31 /// Pipe video interface starts
32 ///
33 
34 /**
35  * creates a video decoder
36  */
37 struct pipe_video_codec *
38 d3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templ);
39 
40 /**
41  * destroy this video decoder
42  */
43 void
44 d3d12_video_decoder_destroy(struct pipe_video_codec *codec);
45 
46 /**
47  * start decoding of a new frame
48  */
49 void
50 d3d12_video_decoder_begin_frame(struct pipe_video_codec * codec,
51                                 struct pipe_video_buffer *target,
52                                 struct pipe_picture_desc *picture);
53 
54 /**
55  * decode a bitstream
56  */
57 void
58 d3d12_video_decoder_decode_bitstream(struct pipe_video_codec * codec,
59                                      struct pipe_video_buffer *target,
60                                      struct pipe_picture_desc *picture,
61                                      unsigned                  num_buffers,
62                                      const void *const *       buffers,
63                                      const unsigned *          sizes);
64 
65 /**
66  * end decoding of the current frame
67  */
68 int
69 d3d12_video_decoder_end_frame(struct pipe_video_codec * codec,
70                               struct pipe_video_buffer *target,
71                               struct pipe_picture_desc *picture);
72 
73 /**
74  * flush any outstanding command buffers to the hardware
75  * should be called before a video_buffer is acessed by the gallium frontend again
76  */
77 void
78 d3d12_video_decoder_flush(struct pipe_video_codec *codec);
79 
80 /**
81  * Get decoder fence.
82  */
83 int d3d12_video_decoder_get_decoder_fence(struct pipe_video_codec *codec,
84                                           struct pipe_fence_handle *fence,
85                                           uint64_t timeout);
86 
87 ///
88 /// Pipe video interface ends
89 ///
90 
91 ///
92 /// d3d12_video_decoder functions starts
93 ///
94 
95 // We need enough to so next item in pipeline doesn't ask for a fence value we lost
96 const uint64_t D3D12_VIDEO_DEC_ASYNC_DEPTH = 36;
97 
98 struct d3d12_video_decoder_reference_poc_entry {
99    uint8_t refpicset_index;
100    int32_t poc_value;
101 };
102 
103 struct d3d12_video_decoder
104 {
105    struct pipe_video_codec base;
106    struct pipe_screen *    m_screen;
107    struct d3d12_screen *   m_pD3D12Screen;
108 
109    ///
110    /// D3D12 objects and context info
111    ///
112 
113    const uint m_NodeMask  = 0u;
114    const uint m_NodeIndex = 0u;
115 
116    ComPtr<ID3D12Fence> m_spFence;
117    uint                m_fenceValue = 1u;
118 
119    ComPtr<ID3D12VideoDevice>             m_spD3D12VideoDevice;
120    ComPtr<ID3D12VideoDecoder>            m_spVideoDecoder;
121    ComPtr<ID3D12VideoDecoderHeap>        m_spVideoDecoderHeap;
122    ComPtr<ID3D12CommandQueue>            m_spDecodeCommandQueue;
123    ComPtr<ID3D12VideoDecodeCommandList1> m_spDecodeCommandList;
124 
125    std::vector<D3D12_RESOURCE_BARRIER> m_transitionsBeforeCloseCmdList;
126    std::vector<D3D12_RESOURCE_BARRIER> m_transitionsStorage;
127 
128    D3D12_VIDEO_DECODER_DESC               m_decoderDesc     = {};
129    D3D12_VIDEO_DECODER_HEAP_DESC          m_decoderHeapDesc = {};
130    D3D12_VIDEO_DECODE_TIER                m_tier            = D3D12_VIDEO_DECODE_TIER_NOT_SUPPORTED;
131    DXGI_FORMAT                            m_decodeFormat;
132    D3D12_FEATURE_DATA_FORMAT_INFO         m_decodeFormatInfo           = {};
133    D3D12_VIDEO_DECODE_CONFIGURATION_FLAGS m_configurationFlags         = D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_NONE;
134    GUID                                   m_d3d12DecProfile            = {};
135    d3d12_video_decode_profile_type        m_d3d12DecProfileType        = {};
136    uint                                   m_ConfigDecoderSpecificFlags = 0u;
137 
138    ///
139    /// Current frame tracked state
140    ///
141 
142    // Tracks DPB and reference picture textures
143    std::shared_ptr<d3d12_video_decoder_references_manager> m_spDPBManager;
144 
145    static const uint64_t m_InitialCompBitstreamGPUBufferSize = (1024 /*1K*/ * 1024 /*1MB*/) * 8 /*8 MB*/;   // 8MB
146 
147    struct InFlightDecodeResources
148    {
149       struct pipe_fence_handle *m_pBitstreamUploadGPUCompletionFence;
150 
151       struct d3d12_fence m_FenceData;
152 
153       // In case of reconfigurations that trigger creation of new
154       // decoder or decoderheap or reference frames allocations
155       // we need to keep a reference alive to the ones that
156       // are currently in-flight
157       ComPtr<ID3D12VideoDecoder>            m_spDecoder;
158       ComPtr<ID3D12VideoDecoderHeap>        m_spDecoderHeap;
159 
160       // Tracks DPB and reference picture textures
161       std::shared_ptr<d3d12_video_decoder_references_manager> m_References;
162 
163       ComPtr<ID3D12CommandAllocator> m_spCommandAllocator;
164       // Holds the input bitstream buffer while it's being constructed in decode_bitstream calls
165       std::vector<uint8_t> m_stagingDecodeBitstream;
166 
167       // Holds the input bitstream buffer in GPU video memory
168       ComPtr<ID3D12Resource> m_curFrameCompressedBitstreamBuffer;
169 
170       // Actual number of allocated bytes available in the buffer (after
171       // m_curFrameCompressedBitstreamBufferPayloadSize might be garbage)
172       uint64_t               m_curFrameCompressedBitstreamBufferAllocatedSize =0;
173       uint64_t m_curFrameCompressedBitstreamBufferPayloadSize = 0u;   // Actual number of bytes of valid data
174 
175       // Holds a buffer for the DXVA struct layout of the picture params of the current frame
176       std::vector<uint8_t> m_picParamsBuffer;   // size() has the byte size of the currently held picparams ; capacity()
177                                                 // has the underlying container allocation size
178 
179       // Set for each frame indicating whether to send VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX
180       bool qp_matrix_frame_argument_enabled = false;
181 
182       // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX of the
183       // current frame m_InverseQuantMatrixBuffer.size() == 0 means no quantization matrix buffer is set for current frame
184       std::vector<uint8_t> m_InverseQuantMatrixBuffer;   // size() has the byte size of the currently held
185                                                          // VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX ;
186                                                          // capacity() has the underlying container allocation size
187 
188       // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL of the current frame
189       // m_SliceControlBuffer.size() == 0 means no quantization matrix buffer is set for current frame
190       std::vector<uint8_t>
191          m_SliceControlBuffer;   // size() has the byte size of the currently held VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL ;
192                                  // capacity() has the underlying container allocation size
193 
194       pipe_resource* pPipeCompressedBufferObj = NULL;
195    };
196 
197    std::vector<InFlightDecodeResources> m_inflightResourcesPool;
198 
199    // Holds pointers to current decode output target texture and reference textures from upper layer
200    struct pipe_video_buffer *m_pCurrentDecodeTarget;
201    struct pipe_video_buffer **m_pCurrentReferenceTargets;
202 
203    // Indicates if GPU commands have not been flushed and are pending.
204    bool m_needsGPUFlush = false;
205 
206    std::vector<d3d12_video_decoder_reference_poc_entry> m_ReferencesConversionStorage;
207 };
208 
209 bool
210 d3d12_video_decoder_create_command_objects(const struct d3d12_screen * pD3D12Screen,
211                                            struct d3d12_video_decoder *pD3D12Dec);
212 bool
213 d3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen * pD3D12Screen,
214                                                   struct d3d12_video_decoder *pD3D12Dec);
215 bool
216 d3d12_video_decoder_create_video_state_buffers(const struct d3d12_screen * pD3D12Screen,
217                                                struct d3d12_video_decoder *pD3D12Dec);
218 bool
219 d3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen * pD3D12Screen,
220                                                     struct d3d12_video_decoder *pD3D12Dec,
221                                                     uint64_t                    bufSize);
222 void
223 d3d12_video_decoder_store_upper_layer_references(struct d3d12_video_decoder *pD3D12Dec,
224                                                 struct pipe_video_buffer *target,
225                                                 struct pipe_picture_desc *picture);
226 bool
227 d3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12Dec,
228                                              struct pipe_video_buffer *  pCurrentDecodeTarget,
229                                              struct d3d12_video_buffer * pD3D12VideoBuffer,
230                                              ID3D12Resource **           ppOutTexture2D,
231                                              uint32_t *                  pOutSubresourceIndex,
232                                              ID3D12Resource **           ppRefOnlyOutTexture2D,
233                                              uint32_t *                  pRefOnlyOutSubresourceIndex,
234                                              const d3d12_video_decode_output_conversion_arguments &conversionArgs);
235 void
236 d3d12_video_decoder_refresh_dpb_active_references(struct d3d12_video_decoder *pD3D12Dec);
237 bool
238 d3d12_video_decoder_reconfigure_dpb(struct d3d12_video_decoder *                          pD3D12Dec,
239                                     struct d3d12_video_buffer *                           pD3D12VideoBuffer,
240                                     const d3d12_video_decode_output_conversion_arguments &conversionArguments);
241 void
242 d3d12_video_decoder_get_frame_info(
243    struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB);
244 void
245 d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(struct d3d12_video_decoder *codec,
246                                                                    struct pipe_picture_desc *  picture,
247                                                                    struct d3d12_video_buffer * pD3D12VideoBuffer);
248 
249 uint64_t
250 d3d12_video_decoder_pool_current_index(struct d3d12_video_decoder *pD3D12Dec);
251 
252 template <typename T>
253 T *
d3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder * codec)254 d3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder *codec)
255 {
256    struct d3d12_video_decoder *pD3D12Dec = (struct d3d12_video_decoder *) codec;
257    assert(pD3D12Dec);
258    return reinterpret_cast<T *>(codec->m_inflightResourcesPool[d3d12_video_decoder_pool_current_index(pD3D12Dec)].m_picParamsBuffer.data());
259 }
260 bool
261 d3d12_video_decoder_supports_aot_dpb(D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT decodeSupport,
262                                      d3d12_video_decode_profile_type         profileType);
263 d3d12_video_decode_profile_type
264 d3d12_video_decoder_convert_pipe_video_profile_to_profile_type(enum pipe_video_profile profile);
265 GUID
266 d3d12_video_decoder_resolve_profile(d3d12_video_decode_profile_type profileType, DXGI_FORMAT decode_format);
267 void
268 d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(struct d3d12_video_decoder *codec,
269                                                              void *                      pDXVABuffer,
270                                                              uint64_t                    DXVABufferSize);
271 void
272 d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(struct d3d12_video_decoder *pD3D12Dec,
273                                                          void *                      pDXVAStruct,
274                                                          uint64_t                    DXVAStructSize);
275 void
276 d3d12_video_decoder_prepare_dxva_slices_control(struct d3d12_video_decoder *pD3D12Dec, struct pipe_picture_desc *picture);
277 
278 bool
279 d3d12_video_decoder_ensure_fence_finished(struct pipe_video_codec *codec, ID3D12Fence* fence, uint64_t fenceValueToWaitOn, uint64_t timeout_ns);
280 
281 bool
282 d3d12_video_decoder_sync_completion(struct pipe_video_codec *codec, ID3D12Fence* fence, uint64_t fenceValueToWaitOn, uint64_t timeout_ns);
283 
284 ///
285 /// d3d12_video_decoder functions ends
286 ///
287 
288 #endif
289