1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#ifndef D3D12_VIDEO_DEC_H
25bf215546Sopenharmony_ci#define D3D12_VIDEO_DEC_H
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include "d3d12_video_types.h"
28bf215546Sopenharmony_ci#include "d3d12_video_dec_references_mgr.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci///
31bf215546Sopenharmony_ci/// Pipe video interface starts
32bf215546Sopenharmony_ci///
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci/**
35bf215546Sopenharmony_ci * creates a video decoder
36bf215546Sopenharmony_ci */
37bf215546Sopenharmony_cistruct pipe_video_codec *
38bf215546Sopenharmony_cid3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templ);
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci/**
41bf215546Sopenharmony_ci * destroy this video decoder
42bf215546Sopenharmony_ci */
43bf215546Sopenharmony_civoid
44bf215546Sopenharmony_cid3d12_video_decoder_destroy(struct pipe_video_codec *codec);
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci/**
47bf215546Sopenharmony_ci * start decoding of a new frame
48bf215546Sopenharmony_ci */
49bf215546Sopenharmony_civoid
50bf215546Sopenharmony_cid3d12_video_decoder_begin_frame(struct pipe_video_codec * codec,
51bf215546Sopenharmony_ci                                struct pipe_video_buffer *target,
52bf215546Sopenharmony_ci                                struct pipe_picture_desc *picture);
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci/**
55bf215546Sopenharmony_ci * decode a bitstream
56bf215546Sopenharmony_ci */
57bf215546Sopenharmony_civoid
58bf215546Sopenharmony_cid3d12_video_decoder_decode_bitstream(struct pipe_video_codec * codec,
59bf215546Sopenharmony_ci                                     struct pipe_video_buffer *target,
60bf215546Sopenharmony_ci                                     struct pipe_picture_desc *picture,
61bf215546Sopenharmony_ci                                     unsigned                  num_buffers,
62bf215546Sopenharmony_ci                                     const void *const *       buffers,
63bf215546Sopenharmony_ci                                     const unsigned *          sizes);
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci/**
66bf215546Sopenharmony_ci * end decoding of the current frame
67bf215546Sopenharmony_ci */
68bf215546Sopenharmony_civoid
69bf215546Sopenharmony_cid3d12_video_decoder_end_frame(struct pipe_video_codec * codec,
70bf215546Sopenharmony_ci                              struct pipe_video_buffer *target,
71bf215546Sopenharmony_ci                              struct pipe_picture_desc *picture);
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci/**
74bf215546Sopenharmony_ci * flush any outstanding command buffers to the hardware
75bf215546Sopenharmony_ci * should be called before a video_buffer is acessed by the gallium frontend again
76bf215546Sopenharmony_ci */
77bf215546Sopenharmony_civoid
78bf215546Sopenharmony_cid3d12_video_decoder_flush(struct pipe_video_codec *codec);
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci///
81bf215546Sopenharmony_ci/// Pipe video interface ends
82bf215546Sopenharmony_ci///
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci///
85bf215546Sopenharmony_ci/// d3d12_video_decoder functions starts
86bf215546Sopenharmony_ci///
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_cistruct d3d12_video_decoder
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   struct pipe_video_codec base;
91bf215546Sopenharmony_ci   struct pipe_screen *    m_screen;
92bf215546Sopenharmony_ci   struct d3d12_screen *   m_pD3D12Screen;
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   ///
95bf215546Sopenharmony_ci   /// D3D12 objects and context info
96bf215546Sopenharmony_ci   ///
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci   const uint m_NodeMask  = 0u;
99bf215546Sopenharmony_ci   const uint m_NodeIndex = 0u;
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   ComPtr<ID3D12Fence> m_spFence;
102bf215546Sopenharmony_ci   uint                m_fenceValue = 1u;
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   ComPtr<ID3D12VideoDevice>             m_spD3D12VideoDevice;
105bf215546Sopenharmony_ci   ComPtr<ID3D12VideoDecoder>            m_spVideoDecoder;
106bf215546Sopenharmony_ci   ComPtr<ID3D12VideoDecoderHeap>        m_spVideoDecoderHeap;
107bf215546Sopenharmony_ci   ComPtr<ID3D12CommandQueue>            m_spDecodeCommandQueue;
108bf215546Sopenharmony_ci   ComPtr<ID3D12CommandAllocator>        m_spCommandAllocator;
109bf215546Sopenharmony_ci   ComPtr<ID3D12VideoDecodeCommandList1> m_spDecodeCommandList;
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci   std::vector<D3D12_RESOURCE_BARRIER> m_transitionsBeforeCloseCmdList;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   D3D12_VIDEO_DECODER_DESC               m_decoderDesc     = {};
114bf215546Sopenharmony_ci   D3D12_VIDEO_DECODER_HEAP_DESC          m_decoderHeapDesc = {};
115bf215546Sopenharmony_ci   D3D12_VIDEO_DECODE_TIER                m_tier            = D3D12_VIDEO_DECODE_TIER_NOT_SUPPORTED;
116bf215546Sopenharmony_ci   DXGI_FORMAT                            m_decodeFormat;
117bf215546Sopenharmony_ci   D3D12_FEATURE_DATA_FORMAT_INFO         m_decodeFormatInfo           = {};
118bf215546Sopenharmony_ci   D3D12_VIDEO_DECODE_CONFIGURATION_FLAGS m_configurationFlags         = D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_NONE;
119bf215546Sopenharmony_ci   GUID                                   m_d3d12DecProfile            = {};
120bf215546Sopenharmony_ci   d3d12_video_decode_profile_type        m_d3d12DecProfileType        = {};
121bf215546Sopenharmony_ci   uint                                   m_ConfigDecoderSpecificFlags = 0u;
122bf215546Sopenharmony_ci
123bf215546Sopenharmony_ci   ///
124bf215546Sopenharmony_ci   /// Current frame tracked state
125bf215546Sopenharmony_ci   ///
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci   // Tracks DPB and reference picture textures
128bf215546Sopenharmony_ci   std::unique_ptr<d3d12_video_decoder_references_manager> m_spDPBManager;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci   // Holds pointers to current decode output target texture and reference textures from upper layer
131bf215546Sopenharmony_ci   struct pipe_video_buffer *m_pCurrentDecodeTarget;
132bf215546Sopenharmony_ci   struct pipe_video_buffer **m_pCurrentReferenceTargets;
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   // Holds the input bitstream buffer while it's being constructed in decode_bitstream calls
135bf215546Sopenharmony_ci   std::vector<uint8_t> m_stagingDecodeBitstream;
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci   const uint64_t m_InitialCompBitstreamGPUBufferSize = (1024 /*1K*/ * 1024 /*1MB*/) * 8 /*8 MB*/;   // 8MB
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   // Holds the input bitstream buffer in GPU video memory
140bf215546Sopenharmony_ci   ComPtr<ID3D12Resource> m_curFrameCompressedBitstreamBuffer;
141bf215546Sopenharmony_ci   uint64_t               m_curFrameCompressedBitstreamBufferAllocatedSize =
142bf215546Sopenharmony_ci      m_InitialCompBitstreamGPUBufferSize;   // Actual number of allocated bytes available in the buffer (after
143bf215546Sopenharmony_ci                                             // m_curFrameCompressedBitstreamBufferPayloadSize might be garbage)
144bf215546Sopenharmony_ci   uint64_t m_curFrameCompressedBitstreamBufferPayloadSize = 0u;   // Actual number of bytes of valid data
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci   // Holds a buffer for the DXVA struct layout of the picture params of the current frame
147bf215546Sopenharmony_ci   std::vector<uint8_t> m_picParamsBuffer;   // size() has the byte size of the currently held picparams ; capacity()
148bf215546Sopenharmony_ci                                             // has the underlying container allocation size
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX of the
151bf215546Sopenharmony_ci   // current frame m_InverseQuantMatrixBuffer.size() == 0 means no quantization matrix buffer is set for current frame
152bf215546Sopenharmony_ci   std::vector<uint8_t> m_InverseQuantMatrixBuffer;   // size() has the byte size of the currently held
153bf215546Sopenharmony_ci                                                      // VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX ;
154bf215546Sopenharmony_ci                                                      // capacity() has the underlying container allocation size
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL of the current frame
157bf215546Sopenharmony_ci   // m_SliceControlBuffer.size() == 0 means no quantization matrix buffer is set for current frame
158bf215546Sopenharmony_ci   std::vector<uint8_t>
159bf215546Sopenharmony_ci      m_SliceControlBuffer;   // size() has the byte size of the currently held VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL ;
160bf215546Sopenharmony_ci                              // capacity() has the underlying container allocation size
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   // Indicates if GPU commands have not been flushed and are pending.
163bf215546Sopenharmony_ci   bool m_needsGPUFlush = false;
164bf215546Sopenharmony_ci};
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_cibool
167bf215546Sopenharmony_cid3d12_video_decoder_create_command_objects(const struct d3d12_screen * pD3D12Screen,
168bf215546Sopenharmony_ci                                           struct d3d12_video_decoder *pD3D12Dec);
169bf215546Sopenharmony_cibool
170bf215546Sopenharmony_cid3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen * pD3D12Screen,
171bf215546Sopenharmony_ci                                                  struct d3d12_video_decoder *pD3D12Dec);
172bf215546Sopenharmony_cibool
173bf215546Sopenharmony_cid3d12_video_decoder_create_video_state_buffers(const struct d3d12_screen * pD3D12Screen,
174bf215546Sopenharmony_ci                                               struct d3d12_video_decoder *pD3D12Dec);
175bf215546Sopenharmony_cibool
176bf215546Sopenharmony_cid3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen * pD3D12Screen,
177bf215546Sopenharmony_ci                                                    struct d3d12_video_decoder *pD3D12Dec,
178bf215546Sopenharmony_ci                                                    uint64_t                    bufSize);
179bf215546Sopenharmony_civoid
180bf215546Sopenharmony_cid3d12_video_decoder_store_upper_layer_references(struct d3d12_video_decoder *pD3D12Dec,
181bf215546Sopenharmony_ci                                                struct pipe_video_buffer *target,
182bf215546Sopenharmony_ci                                                struct pipe_picture_desc *picture);
183bf215546Sopenharmony_cibool
184bf215546Sopenharmony_cid3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12Dec,
185bf215546Sopenharmony_ci                                             struct pipe_video_buffer *  pCurrentDecodeTarget,
186bf215546Sopenharmony_ci                                             struct d3d12_video_buffer * pD3D12VideoBuffer,
187bf215546Sopenharmony_ci                                             ID3D12Resource **           ppOutTexture2D,
188bf215546Sopenharmony_ci                                             uint32_t *                  pOutSubresourceIndex,
189bf215546Sopenharmony_ci                                             ID3D12Resource **           ppRefOnlyOutTexture2D,
190bf215546Sopenharmony_ci                                             uint32_t *                  pRefOnlyOutSubresourceIndex,
191bf215546Sopenharmony_ci                                             const d3d12_video_decode_output_conversion_arguments &conversionArgs);
192bf215546Sopenharmony_civoid
193bf215546Sopenharmony_cid3d12_video_decoder_refresh_dpb_active_references(struct d3d12_video_decoder *pD3D12Dec);
194bf215546Sopenharmony_cibool
195bf215546Sopenharmony_cid3d12_video_decoder_reconfigure_dpb(struct d3d12_video_decoder *                          pD3D12Dec,
196bf215546Sopenharmony_ci                                    struct d3d12_video_buffer *                           pD3D12VideoBuffer,
197bf215546Sopenharmony_ci                                    const d3d12_video_decode_output_conversion_arguments &conversionArguments);
198bf215546Sopenharmony_civoid
199bf215546Sopenharmony_cid3d12_video_decoder_get_frame_info(
200bf215546Sopenharmony_ci   struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB, bool &isInterlaced);
201bf215546Sopenharmony_civoid
202bf215546Sopenharmony_cid3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(struct d3d12_video_decoder *codec,
203bf215546Sopenharmony_ci                                                                   struct pipe_picture_desc *  picture,
204bf215546Sopenharmony_ci                                                                   struct d3d12_video_buffer * pD3D12VideoBuffer);
205bf215546Sopenharmony_citemplate <typename T>
206bf215546Sopenharmony_ciT *
207bf215546Sopenharmony_cid3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder *codec)
208bf215546Sopenharmony_ci{
209bf215546Sopenharmony_ci   return reinterpret_cast<T *>(codec->m_picParamsBuffer.data());
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_cibool
212bf215546Sopenharmony_cid3d12_video_decoder_supports_aot_dpb(D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT decodeSupport,
213bf215546Sopenharmony_ci                                     d3d12_video_decode_profile_type         profileType);
214bf215546Sopenharmony_cid3d12_video_decode_profile_type
215bf215546Sopenharmony_cid3d12_video_decoder_convert_pipe_video_profile_to_profile_type(enum pipe_video_profile profile);
216bf215546Sopenharmony_ciGUID
217bf215546Sopenharmony_cid3d12_video_decoder_resolve_profile(d3d12_video_decode_profile_type profileType);
218bf215546Sopenharmony_civoid
219bf215546Sopenharmony_cid3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(struct d3d12_video_decoder *codec,
220bf215546Sopenharmony_ci                                                             void *                      pDXVABuffer,
221bf215546Sopenharmony_ci                                                             uint64_t                    DXVABufferSize);
222bf215546Sopenharmony_civoid
223bf215546Sopenharmony_cid3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(struct d3d12_video_decoder *pD3D12Dec,
224bf215546Sopenharmony_ci                                                         void *                      pDXVAStruct,
225bf215546Sopenharmony_ci                                                         uint64_t                    DXVAStructSize);
226bf215546Sopenharmony_civoid
227bf215546Sopenharmony_cid3d12_video_decoder_prepare_dxva_slices_control(struct d3d12_video_decoder *pD3D12Dec, struct pipe_picture_desc *picture);
228bf215546Sopenharmony_civoid
229bf215546Sopenharmony_cid3d12_video_decoder_store_dxva_slicecontrol_in_slicecontrol_buffer(struct d3d12_video_decoder *pD3D12Dec,
230bf215546Sopenharmony_ci                                                                   void *                      pDXVAStruct,
231bf215546Sopenharmony_ci                                                                   uint64_t                    DXVAStructSize);
232bf215546Sopenharmony_ciint
233bf215546Sopenharmony_cid3d12_video_decoder_get_next_startcode_offset(std::vector<uint8_t> &buf,
234bf215546Sopenharmony_ci                                              unsigned int          bufferOffset,
235bf215546Sopenharmony_ci                                              unsigned int          targetCode,
236bf215546Sopenharmony_ci                                              unsigned int          targetCodeBitSize,
237bf215546Sopenharmony_ci                                              unsigned int          numBitsToSearchIntoBuffer);
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci///
240bf215546Sopenharmony_ci/// d3d12_video_decoder functions ends
241bf215546Sopenharmony_ci///
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci#endif
244