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 void
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 /// Pipe video interface ends
82 ///
83
84 ///
85 /// d3d12_video_decoder functions starts
86 ///
87
88 struct 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
166 bool
167 d3d12_video_decoder_create_command_objects(const struct d3d12_screen * pD3D12Screen,
168 struct d3d12_video_decoder *pD3D12Dec);
169 bool
170 d3d12_video_decoder_check_caps_and_create_decoder(const struct d3d12_screen * pD3D12Screen,
171 struct d3d12_video_decoder *pD3D12Dec);
172 bool
173 d3d12_video_decoder_create_video_state_buffers(const struct d3d12_screen * pD3D12Screen,
174 struct d3d12_video_decoder *pD3D12Dec);
175 bool
176 d3d12_video_decoder_create_staging_bitstream_buffer(const struct d3d12_screen * pD3D12Screen,
177 struct d3d12_video_decoder *pD3D12Dec,
178 uint64_t bufSize);
179 void
180 d3d12_video_decoder_store_upper_layer_references(struct d3d12_video_decoder *pD3D12Dec,
181 struct pipe_video_buffer *target,
182 struct pipe_picture_desc *picture);
183 bool
184 d3d12_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);
192 void
193 d3d12_video_decoder_refresh_dpb_active_references(struct d3d12_video_decoder *pD3D12Dec);
194 bool
195 d3d12_video_decoder_reconfigure_dpb(struct d3d12_video_decoder * pD3D12Dec,
196 struct d3d12_video_buffer * pD3D12VideoBuffer,
197 const d3d12_video_decode_output_conversion_arguments &conversionArguments);
198 void
199 d3d12_video_decoder_get_frame_info(
200 struct d3d12_video_decoder *pD3D12Dec, uint32_t *pWidth, uint32_t *pHeight, uint16_t *pMaxDPB, bool &isInterlaced);
201 void
202 d3d12_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);
205 template <typename T>
206 T *
d3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder * codec)207 d3d12_video_decoder_get_current_dxva_picparams(struct d3d12_video_decoder *codec)
208 {
209 return reinterpret_cast<T *>(codec->m_picParamsBuffer.data());
210 }
211 bool
212 d3d12_video_decoder_supports_aot_dpb(D3D12_FEATURE_DATA_VIDEO_DECODE_SUPPORT decodeSupport,
213 d3d12_video_decode_profile_type profileType);
214 d3d12_video_decode_profile_type
215 d3d12_video_decoder_convert_pipe_video_profile_to_profile_type(enum pipe_video_profile profile);
216 GUID
217 d3d12_video_decoder_resolve_profile(d3d12_video_decode_profile_type profileType);
218 void
219 d3d12_video_decoder_store_dxva_picparams_in_picparams_buffer(struct d3d12_video_decoder *codec,
220 void * pDXVABuffer,
221 uint64_t DXVABufferSize);
222 void
223 d3d12_video_decoder_store_dxva_qmatrix_in_qmatrix_buffer(struct d3d12_video_decoder *pD3D12Dec,
224 void * pDXVAStruct,
225 uint64_t DXVAStructSize);
226 void
227 d3d12_video_decoder_prepare_dxva_slices_control(struct d3d12_video_decoder *pD3D12Dec, struct pipe_picture_desc *picture);
228 void
229 d3d12_video_decoder_store_dxva_slicecontrol_in_slicecontrol_buffer(struct d3d12_video_decoder *pD3D12Dec,
230 void * pDXVAStruct,
231 uint64_t DXVAStructSize);
232 int
233 d3d12_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