1 /*
2 * Copyright (c) 2017, Intel 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 shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     mhw_vdbox_hcp_g9_skl.cpp
24 //! \brief    Defines functions for constructing Vdbox HCP commands on G9 SKL
25 //!
26 
27 #include "mhw_vdbox_hcp_g9_skl.h"
28 #include "mhw_mi_hwcmd_g9_X.h"
29 #include "mhw_vdbox_vdenc_hwcmd_g9_skl.h"
30 
GetHcpStateCommandSize(uint32_t mode,uint32_t * commandsSize,uint32_t * patchListSize,PMHW_VDBOX_STATE_CMDSIZE_PARAMS params)31 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::GetHcpStateCommandSize(
32     uint32_t                        mode,
33     uint32_t                        *commandsSize,
34     uint32_t                        *patchListSize,
35     PMHW_VDBOX_STATE_CMDSIZE_PARAMS params)
36 {
37     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
38 
39     MHW_FUNCTION_ENTER;
40 
41     uint32_t            maxSize = 0;
42     uint32_t            patchListMaxSize = 0;
43     uint32_t            standard = CodecHal_GetStandardFromMode(mode);
44 
45     if (standard == CODECHAL_HEVC)
46     {
47         maxSize =
48             mhw_vdbox_vdenc_g9_skl::VD_PIPELINE_FLUSH_CMD::byteSize +
49             mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize +
50             mhw_vdbox_hcp_g9_skl::HCP_PIPE_MODE_SELECT_CMD::byteSize +
51             mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD::byteSize +
52             mhw_vdbox_hcp_g9_skl::HCP_PIPE_BUF_ADDR_STATE_CMD::byteSize +
53             mhw_vdbox_hcp_g9_skl::HCP_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize;
54 
55         patchListMaxSize =
56             PATCH_LIST_COMMAND(VD_PIPELINE_FLUSH_CMD) +
57             PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) +
58             PATCH_LIST_COMMAND(HCP_PIPE_MODE_SELECT_CMD) +
59             PATCH_LIST_COMMAND(HCP_SURFACE_STATE_CMD) +
60             PATCH_LIST_COMMAND(HCP_PIPE_BUF_ADDR_STATE_CMD) +
61             PATCH_LIST_COMMAND(HCP_IND_OBJ_BASE_ADDR_STATE_CMD);
62 
63         if (mode == CODECHAL_ENCODE_MODE_HEVC)
64         {
65             /* HCP_QM_STATE_CMD may be issued up to 20 times: 3x Colour Component plus 2x intra/inter plus 4x SizeID minus 4 for the 32x32 chroma components.
66             HCP_FQP_STATE_CMD may be issued up to 8 times: 4 scaling list per intra and inter. */
67             maxSize +=
68                 mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD::byteSize + // encoder needs two surface state commands. One is for raw and another one is for recon surfaces.
69                 20 * mhw_vdbox_hcp_g9_skl::HCP_QM_STATE_CMD::byteSize +
70                 8 * mhw_vdbox_hcp_g9_skl::HCP_FQM_STATE_CMD::byteSize +
71                 mhw_vdbox_hcp_g9_skl::HCP_PIC_STATE_CMD::byteSize +
72                 2 * mhw_mi_g9_X::MI_STORE_DATA_IMM_CMD::byteSize + // Slice level commands
73                 2 * mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize + // need for Status report, Mfc Status and
74                 10 * mhw_mi_g9_X::MI_STORE_REGISTER_MEM_CMD::byteSize + // 8 for BRCStatistics and 2 for RC6 WAs
75                 mhw_mi_g9_X::MI_LOAD_REGISTER_MEM_CMD::byteSize + // 1 for RC6
76                 2 * mhw_vdbox_hcp_g9_skl::HCP_PAK_INSERT_OBJECT_CMD::byteSize + // Two PAK insert object commands are for headers before the slice header and the header for the end of stream
77                 4 * mhw_mi_g9_X::MI_STORE_DATA_IMM_CMD::byteSize + // two (BRC+reference frame) for clean-up HW semaphore memory and another two for signal it
78                 17 * mhw_mi_g9_X::MI_SEMAPHORE_WAIT_CMD::byteSize + // Use HW wait command for each reference and one wait for current semaphore object
79                 mhw_mi_g9_X::MI_SEMAPHORE_WAIT_CMD::byteSize;        // Use HW wait command for each BRC pass
80 
81             patchListMaxSize +=
82                 20 * PATCH_LIST_COMMAND(HCP_QM_STATE_CMD) +
83                 8 * PATCH_LIST_COMMAND(HCP_FQM_STATE_CMD) +
84                 PATCH_LIST_COMMAND(HCP_PIC_STATE_CMD) +
85                 PATCH_LIST_COMMAND(MI_BATCH_BUFFER_START_CMD) + // When BRC is on, HCP_PIC_STATE_CMD command is in the BB
86                 2 * PATCH_LIST_COMMAND(MI_STORE_DATA_IMM_CMD) + // Slice level commands
87                 2 * PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) + // need for Status report, Mfc Status and
88                 11 * PATCH_LIST_COMMAND(MI_STORE_REGISTER_MEM_CMD) +// 8 for BRCStatistics and 3 for RC6 WAs
89                 22 * PATCH_LIST_COMMAND(MI_STORE_DATA_IMM_CMD); // Use HW wait commands plus its memory clean-up and signal (4 + 16 +1 + 1)
90         }
91         else
92         {
93             maxSize +=
94                 20 * mhw_vdbox_hcp_g9_skl::HCP_QM_STATE_CMD::byteSize +
95                 mhw_vdbox_hcp_g9_skl::HCP_PIC_STATE_CMD::byteSize +
96                 mhw_vdbox_hcp_g9_skl::HCP_TILE_STATE_CMD::byteSize;
97 
98             patchListMaxSize +=
99                 20 * PATCH_LIST_COMMAND(HCP_QM_STATE_CMD) +
100                 PATCH_LIST_COMMAND(HCP_PIC_STATE_CMD) +
101                 PATCH_LIST_COMMAND(HCP_TILE_STATE_CMD);
102         }
103     }
104     else if (standard == CODECHAL_VP9)     // VP9 Clear Decode
105     {
106         maxSize =
107             mhw_vdbox_vdenc_g9_skl::VD_PIPELINE_FLUSH_CMD::byteSize +
108             mhw_mi_g9_X::MI_FLUSH_DW_CMD::byteSize +
109             mhw_vdbox_hcp_g9_skl::HCP_PIPE_MODE_SELECT_CMD::byteSize +
110             mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD::byteSize * 4 +
111             mhw_vdbox_hcp_g9_skl::HCP_PIPE_BUF_ADDR_STATE_CMD::byteSize +
112             mhw_vdbox_hcp_g9_skl::HCP_IND_OBJ_BASE_ADDR_STATE_CMD::byteSize +
113             mhw_vdbox_hcp_g9_skl::HCP_BSD_OBJECT_CMD::byteSize;
114 
115         patchListMaxSize =
116             PATCH_LIST_COMMAND(VD_PIPELINE_FLUSH_CMD) +
117             PATCH_LIST_COMMAND(MI_FLUSH_DW_CMD) +
118             PATCH_LIST_COMMAND(HCP_PIPE_MODE_SELECT_CMD) +
119             PATCH_LIST_COMMAND(HCP_SURFACE_STATE_CMD) * 4 +
120             PATCH_LIST_COMMAND(HCP_PIPE_BUF_ADDR_STATE_CMD) +
121             PATCH_LIST_COMMAND(HCP_IND_OBJ_BASE_ADDR_STATE_CMD) +
122             PATCH_LIST_COMMAND(HCP_VP9_SEGMENT_STATE_CMD) * 8 +
123             PATCH_LIST_COMMAND(HCP_VP9_PIC_STATE_CMD) +
124             PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
125     }
126     else
127     {
128         MHW_ASSERTMESSAGE("Unsupported standard.");
129         eStatus = MOS_STATUS_UNKNOWN;
130     }
131 
132     *commandsSize = maxSize;
133     *patchListSize = patchListMaxSize;
134 
135     return eStatus;
136 }
137 
GetHcpPrimitiveCommandSize(uint32_t mode,uint32_t * commandsSize,uint32_t * patchListSize,bool modeSpecific)138 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::GetHcpPrimitiveCommandSize(
139     uint32_t                        mode,
140     uint32_t                        *commandsSize,
141     uint32_t                        *patchListSize,
142     bool                            modeSpecific)
143 {
144     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
145 
146     MHW_FUNCTION_ENTER;
147 
148     uint32_t            standard = CodecHal_GetStandardFromMode(mode);
149     uint32_t            maxSize = 0;
150     uint32_t            patchListMaxSize = 0;
151 
152     if (standard == CODECHAL_HEVC)
153     {
154         if (mode == CODECHAL_ENCODE_MODE_HEVC)
155         {
156             maxSize =
157                 2 * mhw_vdbox_hcp_g9_skl::HCP_REF_IDX_STATE_CMD::byteSize +
158                 2 * mhw_vdbox_hcp_g9_skl::HCP_WEIGHTOFFSET_STATE_CMD::byteSize +
159                 mhw_vdbox_hcp_g9_skl::HCP_SLICE_STATE_CMD::byteSize +
160                 mhw_vdbox_hcp_g9_skl::HCP_PAK_INSERT_OBJECT_CMD::byteSize +
161                 mhw_mi_g9_X::MI_BATCH_BUFFER_START_CMD::byteSize;
162 
163             patchListMaxSize =
164                 2 * PATCH_LIST_COMMAND(HCP_REF_IDX_STATE_CMD) +
165                 2 * PATCH_LIST_COMMAND(HCP_WEIGHTOFFSET_STATE_CMD) +
166                 PATCH_LIST_COMMAND(HCP_SLICE_STATE_CMD) +
167                 PATCH_LIST_COMMAND(HCP_PAK_INSERT_OBJECT_CMD) +
168                 2 * PATCH_LIST_COMMAND(MI_BATCH_BUFFER_START_CMD); // One is for the PAK command and another one is for the BB when BRC and single task mode are on
169         }
170         else
171         {
172             maxSize =
173                 2 * mhw_vdbox_hcp_g9_skl::HCP_REF_IDX_STATE_CMD::byteSize +
174                 2 * mhw_vdbox_hcp_g9_skl::HCP_WEIGHTOFFSET_STATE_CMD::byteSize +
175                 mhw_vdbox_hcp_g9_skl::HCP_SLICE_STATE_CMD::byteSize +
176                 mhw_vdbox_hcp_g9_skl::HCP_BSD_OBJECT_CMD::byteSize +
177                 mhw_mi_g9_X::MI_BATCH_BUFFER_END_CMD::byteSize;
178 
179             patchListMaxSize =
180                 2 * PATCH_LIST_COMMAND(HCP_REF_IDX_STATE_CMD) +
181                 2 * PATCH_LIST_COMMAND(HCP_WEIGHTOFFSET_STATE_CMD) +
182                 PATCH_LIST_COMMAND(HCP_SLICE_STATE_CMD) +
183                 PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
184         }
185     }
186     else if (standard == CODECHAL_VP9)      // VP9 Clear decode does not require primitive level commands. VP9 DRM does.
187     {
188         if (modeSpecific)                  // VP9 DRM
189         {
190             maxSize +=
191                 mhw_vdbox_hcp_g9_skl::HCP_BSD_OBJECT_CMD::byteSize +
192                 mhw_mi_g9_X::MI_BATCH_BUFFER_END_CMD::byteSize;
193 
194             patchListMaxSize =
195                 PATCH_LIST_COMMAND(HCP_VP9_SEGMENT_STATE_CMD) * 8 +
196                 PATCH_LIST_COMMAND(HCP_VP9_PIC_STATE_CMD) +
197                 PATCH_LIST_COMMAND(HCP_BSD_OBJECT_CMD);
198         }
199     }
200     else
201     {
202         MHW_ASSERTMESSAGE("Unsupported standard.");
203         eStatus = MOS_STATUS_UNKNOWN;
204     }
205 
206     *commandsSize = maxSize;
207     *patchListSize = patchListMaxSize;
208 
209     return eStatus;
210 }
211 
AddHcpPipeModeSelectCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS params)212  MOS_STATUS MhwVdboxHcpInterfaceG9Skl::AddHcpPipeModeSelectCmd(
213     PMOS_COMMAND_BUFFER                  cmdBuffer,
214     PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS   params)
215 {
216     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
217 
218     MHW_FUNCTION_ENTER;
219 
220     MHW_MI_CHK_NULL(params);
221 
222     mhw_vdbox_hcp_g9_skl::HCP_PIPE_MODE_SELECT_CMD  *cmd =
223         (mhw_vdbox_hcp_g9_skl::HCP_PIPE_MODE_SELECT_CMD*)cmdBuffer->pCmdPtr;
224 
225     MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceG9<mhw_vdbox_hcp_g9_skl>::AddHcpPipeModeSelectCmd(cmdBuffer, params));
226 
227     m_cpInterface->SetProtectionSettingsForMfxPipeModeSelect((uint32_t *)cmd);
228 
229     return eStatus;
230 }
231 
AddHcpDecodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)232 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::AddHcpDecodeSurfaceStateCmd(
233     PMOS_COMMAND_BUFFER              cmdBuffer,
234     PMHW_VDBOX_SURFACE_PARAMS        params)
235 {
236     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
237 
238     MHW_MI_CHK_NULL(params);
239 
240     mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD  *cmd =
241         (mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD*)cmdBuffer->pCmdPtr;
242 
243     MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_skl>::AddHcpDecodeSurfaceStateCmd(cmdBuffer, params));
244 
245     MHW_ASSERT(params->psSurface->Format == Format_NV12);
246 
247     return eStatus;
248 }
249 
AddHcpEncodeSurfaceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_SURFACE_PARAMS params)250 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::AddHcpEncodeSurfaceStateCmd(
251     PMOS_COMMAND_BUFFER              cmdBuffer,
252     PMHW_VDBOX_SURFACE_PARAMS        params)
253 {
254     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
255 
256     MHW_MI_CHK_NULL(params);
257 
258     mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD  *cmd =
259         (mhw_vdbox_hcp_g9_skl::HCP_SURFACE_STATE_CMD*)cmdBuffer->pCmdPtr;
260 
261     MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_skl>::AddHcpEncodeSurfaceStateCmd(cmdBuffer, params));
262 
263     MHW_ASSERT(params->psSurface->Format == Format_NV12);
264 
265     return eStatus;
266 }
267 
AddHcpDecodeSliceStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HEVC_SLICE_STATE hevcSliceState)268 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::AddHcpDecodeSliceStateCmd(
269     PMOS_COMMAND_BUFFER              cmdBuffer,
270     PMHW_VDBOX_HEVC_SLICE_STATE      hevcSliceState)
271 {
272     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
273 
274     MHW_FUNCTION_ENTER;
275 
276     MHW_MI_CHK_NULL(hevcSliceState);
277     MHW_MI_CHK_NULL(hevcSliceState->pHevcPicParams);
278     MHW_MI_CHK_NULL(hevcSliceState->pHevcSliceParams);
279 
280     auto hevcPicParams = hevcSliceState->pHevcPicParams;
281     auto hevcSliceParams = hevcSliceState->pHevcSliceParams;
282 
283     mhw_vdbox_hcp_g9_skl::HCP_SLICE_STATE_CMD  *cmd =
284         (mhw_vdbox_hcp_g9_skl::HCP_SLICE_STATE_CMD*)cmdBuffer->pCmdPtr;
285 
286     MHW_MI_CHK_STATUS(MhwVdboxHcpInterfaceGeneric<mhw_vdbox_hcp_g9_skl>::AddHcpDecodeSliceStateCmd(cmdBuffer, hevcSliceState));
287 
288     cmd->DW3.Sliceqp = hevcSliceParams->slice_qp_delta +
289         hevcPicParams->init_qp_minus26 + 26;
290 
291     return eStatus;
292 }
293 
AddHcpVp9SegmentStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_VP9_SEGMENT_STATE params)294 MOS_STATUS MhwVdboxHcpInterfaceG9Skl::AddHcpVp9SegmentStateCmd(
295     PMOS_COMMAND_BUFFER              cmdBuffer,
296     PMHW_BATCH_BUFFER                batchBuffer,
297     PMHW_VDBOX_VP9_SEGMENT_STATE     params)
298 {
299     return MOS_STATUS_SUCCESS;
300 }