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 */
37struct pipe_video_codec *
38d3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video_codec *templ);
39
40/**
41 * destroy this video decoder
42 */
43void
44d3d12_video_decoder_destroy(struct pipe_video_codec *codec);
45
46/**
47 * start decoding of a new frame
48 */
49void
50d3d12_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 */
57void
58d3d12_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 */
68void
69d3d12_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 */
77void
78d3d12_video_decoder_flush(struct pipe_video_codec *codec);
79
80///
81/// Pipe video interface ends
82///
83
84///
85/// d3d12_video_decoder functions starts
86///
87
88struct d3d12_video_decoder
89{
90   struct pipe_video_codec base;
91   struct pipe_screen *    m_screen;
92   struct d3d12_screen *   m_pD3D12Screen;
93
94   ///
95   /// D3D12 objects and context info
96   ///
97
98   const uint m_NodeMask  = 0u;
99   const uint m_NodeIndex = 0u;
100
101   ComPtr<ID3D12Fence> m_spFence;
102   uint                m_fenceValue = 1u;
103
104   ComPtr<ID3D12VideoDevice>             m_spD3D12VideoDevice;
105   ComPtr<ID3D12VideoDecoder>            m_spVideoDecoder;
106   ComPtr<ID3D12VideoDecoderHeap>        m_spVideoDecoderHeap;
107   ComPtr<ID3D12CommandQueue>            m_spDecodeCommandQueue;
108   ComPtr<ID3D12CommandAllocator>        m_spCommandAllocator;
109   ComPtr<ID3D12VideoDecodeCommandList1> m_spDecodeCommandList;
110
111   std::vector<D3D12_RESOURCE_BARRIER> m_transitionsBeforeCloseCmdList;
112
113   D3D12_VIDEO_DECODER_DESC               m_decoderDesc     = {};
114   D3D12_VIDEO_DECODER_HEAP_DESC          m_decoderHeapDesc = {};
115   D3D12_VIDEO_DECODE_TIER                m_tier            = D3D12_VIDEO_DECODE_TIER_NOT_SUPPORTED;
116   DXGI_FORMAT                            m_decodeFormat;
117   D3D12_FEATURE_DATA_FORMAT_INFO         m_decodeFormatInfo           = {};
118   D3D12_VIDEO_DECODE_CONFIGURATION_FLAGS m_configurationFlags         = D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_NONE;
119   GUID                                   m_d3d12DecProfile            = {};
120   d3d12_video_decode_profile_type        m_d3d12DecProfileType        = {};
121   uint                                   m_ConfigDecoderSpecificFlags = 0u;
122
123   ///
124   /// Current frame tracked state
125   ///
126
127   // Tracks DPB and reference picture textures
128   std::unique_ptr<d3d12_video_decoder_references_manager> m_spDPBManager;
129
130   // Holds pointers to current decode output target texture and reference textures from upper layer
131   struct pipe_video_buffer *m_pCurrentDecodeTarget;
132   struct pipe_video_buffer **m_pCurrentReferenceTargets;
133
134   // Holds the input bitstream buffer while it's being constructed in decode_bitstream calls
135   std::vector<uint8_t> m_stagingDecodeBitstream;
136
137   const uint64_t m_InitialCompBitstreamGPUBufferSize = (1024 /*1K*/ * 1024 /*1MB*/) * 8 /*8 MB*/;   // 8MB
138
139   // Holds the input bitstream buffer in GPU video memory
140   ComPtr<ID3D12Resource> m_curFrameCompressedBitstreamBuffer;
141   uint64_t               m_curFrameCompressedBitstreamBufferAllocatedSize =
142      m_InitialCompBitstreamGPUBufferSize;   // Actual number of allocated bytes available in the buffer (after
143                                             // m_curFrameCompressedBitstreamBufferPayloadSize might be garbage)
144   uint64_t m_curFrameCompressedBitstreamBufferPayloadSize = 0u;   // Actual number of bytes of valid data
145
146   // Holds a buffer for the DXVA struct layout of the picture params of the current frame
147   std::vector<uint8_t> m_picParamsBuffer;   // size() has the byte size of the currently held picparams ; capacity()
148                                             // has the underlying container allocation size
149
150   // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX of the
151   // current frame m_InverseQuantMatrixBuffer.size() == 0 means no quantization matrix buffer is set for current frame
152   std::vector<uint8_t> m_InverseQuantMatrixBuffer;   // size() has the byte size of the currently held
153                                                      // VIDEO_DECODE_BUFFER_TYPE_INVERSE_QUANTIZATION_MATRIX ;
154                                                      // capacity() has the underlying container allocation size
155
156   // Holds a buffer for the DXVA struct layout of the VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL of the current frame
157   // m_SliceControlBuffer.size() == 0 means no quantization matrix buffer is set for current frame
158   std::vector<uint8_t>
159      m_SliceControlBuffer;   // size() has the byte size of the currently held VIDEO_DECODE_BUFFER_TYPE_SLICE_CONTROL ;
160                              // capacity() has the underlying container allocation size
161
162   // Indicates if GPU commands have not been flushed and are pending.
163   bool m_needsGPUFlush = false;
164};
165
166bool
167d3d12_video_decoder_create_command_objects(const struct d3d12_screen * pD3D12Screen,
168                                           struct d3d12_video_decoder *pD3D12Dec);
169bool
170d3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen * pD3D12Screen,
171                                                  struct d3d12_video_decoder *pD3D12Dec);
172bool
173d3d12_video_decoder_create_video_state_buffers(const struct d3d12_screen * pD3D12Screen,
174                                               struct d3d12_video_decoder *pD3D12Dec);
175bool
176d3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen * pD3D12Screen,
177                                                    struct d3d12_video_decoder *pD3D12Dec,
178                                                    uint64_t                    bufSize);
179void
180d3d12_video_decoder_store_upper_layer_references(struct d3d12_video_decoder *pD3D12Dec,
181                                                struct pipe_video_buffer *target,
182                                                struct pipe_picture_desc *picture);
183bool
184d3d12_video_decoder_prepare_for_decode_frame(struct d3d12_video_decoder *pD3D12Dec,
185                                             struct pipe_video_buffer *  pCurrentDecodeTarget,
186                                             struct d3d12_video_buffer * pD3D12VideoBuffer,
187                                             ID3D12Resource **           ppOutTexture2D,
188                                             uint32_t *                  pOutSubresourceIndex,
189                                             ID3D12Resource **           ppRefOnlyOutTexture2D,
190                                             uint32_t *                  pRefOnlyOutSubresourceIndex,
191                                             const d3d12_video_decode_output_conversion_arguments &conversionArgs);
192void
193d3d12_video_decoder_refresh_dpb_active_references(struct d3d12_video_decoder *pD3D12Dec);
194bool
195d3d12_video_decoder_reconfigure_dpb(struct d3d12_video_decoder *                          pD3D12Dec,
196                                    struct d3d12_video_buffer *                           pD3D12VideoBuffer,
197                                    const d3d12_video_decode_output_conversion_arguments &conversionArguments);
198void
199d3d12_video_decoder_get_frame_info(
200   struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB, bool &isInterlaced);
201void
202d3d12_video_decoder_store_converted_dxva_picparams_from_pipe_input(struct d3d12_video_decoder *codec,
203                                                                   struct pipe_picture_desc *  picture,
204                                                                   struct d3d12_video_buffer * pD3D12VideoBuffer);
205template <typename T>
206T *
207d3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder *codec)
208{
209   return reinterpret_cast<T *>(codec->m_picParamsBuffer.data());
210}
211bool
212d3d12_video_decoder_supports_aot_dpb(D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT decodeSupport,
213                                     d3d12_video_decode_profile_type         profileType);
214d3d12_video_decode_profile_type
215d3d12_video_decoder_convert_pipe_video_profile_to_profile_type(enum pipe_video_profile profile);
216GUID
217d3d12_video_decoder_resolve_profile(d3d12_video_decode_profile_type profileType);
218void
219d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(struct d3d12_video_decoder *codec,
220                                                             void *                      pDXVABuffer,
221                                                             uint64_t                    DXVABufferSize);
222void
223d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(struct d3d12_video_decoder *pD3D12Dec,
224                                                         void *                      pDXVAStruct,
225                                                         uint64_t                    DXVAStructSize);
226void
227d3d12_video_decoder_prepare_dxva_slices_control(struct d3d12_video_decoder *pD3D12Dec, struct pipe_picture_desc *picture);
228void
229d3d12_video_decoder_store_dxva_slicecontrol_in_slicecontrol_buffer(struct d3d12_video_decoder *pD3D12Dec,
230                                                                   void *                      pDXVAStruct,
231                                                                   uint64_t                    DXVAStructSize);
232int
233d3d12_video_decoder_get_next_startcode_offset(std::vector<uint8_t> &buf,
234                                              unsigned int          bufferOffset,
235                                              unsigned int          targetCode,
236                                              unsigned int          targetCodeBitSize,
237                                              unsigned int          numBitsToSearchIntoBuffer);
238
239///
240/// d3d12_video_decoder functions ends
241///
242
243#endif
244