1 /*
2 * Copyright (c) 2017-2020, 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     codechal_decode_jpeg_g12.cpp
24 //! \brief    Implements the decode interface extension for JPEG.
25 //! \details  Implements all functions and constants required by CodecHal for JPEG decoding.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_decode_jpeg_g12.h"
30 #include "mhw_vdbox_mfx_g12_X.h"
31 #include "codechal_mmc_decode_jpeg_g12.h"
32 #include "codechal_decode_sfc_jpeg_g12.h"
33 #include "hal_oca_interface.h"
34 
35 
~CodechalDecodeJpegG12()36 CodechalDecodeJpegG12::~CodechalDecodeJpegG12()
37 {
38     CODECHAL_DECODE_FUNCTION_ENTER;
39 
40     if (m_veState != nullptr)
41     {
42         MOS_FreeMemAndSetNull(m_veState);
43         m_veState = nullptr;
44     }
45 }
46 
InitMmcState()47 MOS_STATUS CodechalDecodeJpegG12::InitMmcState()
48 {
49 #ifdef _MMC_SUPPORTED
50     m_mmc = MOS_New(CodechalMmcDecodeJpegG12, m_hwInterface, this);
51     CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
52 #endif
53     return MOS_STATUS_SUCCESS;
54 }
55 
56 #ifdef _DECODE_PROCESSING_SUPPORTED
InitSfcState()57 MOS_STATUS  CodechalDecodeJpegG12::InitSfcState()
58 {
59     m_sfcState = MOS_New(CodechalJpegSfcStateG12);
60     CODECHAL_DECODE_CHK_NULL_RETURN(m_sfcState);
61     return MOS_STATUS_SUCCESS;
62 }
63 #endif
64 
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)65 MOS_STATUS CodechalDecodeJpegG12::SetGpuCtxCreatOption(
66     CodechalSetting *codecHalSetting)
67 {
68     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
69 
70     CODECHAL_DECODE_FUNCTION_ENTER;
71 
72     if (!MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
73     {
74         CodechalDecode::SetGpuCtxCreatOption(codecHalSetting);
75     }
76     else
77     {
78         m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS_ENHANCED);
79         bool sfcInUse    = codecHalSetting->sfcInUseHinted && IsSfcInUse(codecHalSetting);
80         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_ConstructParmsForGpuCtxCreation(
81             m_veState,
82             (PMOS_GPUCTX_CREATOPTIONS_ENHANCED)m_gpuCtxCreatOpt,
83             sfcInUse));
84     }
85 
86     return eStatus;
87 }
88 
SetFrameStates()89 MOS_STATUS CodechalDecodeJpegG12::SetFrameStates()
90 {
91     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
92 
93     CODECHAL_DECODE_FUNCTION_ENTER;
94 
95     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeJpeg::SetFrameStates());
96 
97     if (MOS_VE_SUPPORTED(m_osInterface) && !MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface))
98     {
99         MOS_VIRTUALENGINE_SET_PARAMS  vesetParams;
100 
101         MOS_ZeroMemory(&vesetParams, sizeof(vesetParams));
102 #ifdef _DECODE_PROCESSING_SUPPORTED
103         vesetParams.bSFCInUse = m_sfcState->m_sfcPipeOut;
104 #else
105         vesetParams.bSFCInUse                   = false;
106 #endif
107         vesetParams.bNeedSyncWithPrevious       = true;
108         vesetParams.bSameEngineAsLastSubmission = false;
109         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_SetHintParams(
110             m_veState,
111             &vesetParams));
112     }
113 
114     return eStatus;
115 }
116 
DecodeStateLevel()117 MOS_STATUS CodechalDecodeJpegG12::DecodeStateLevel()
118 {
119     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
120 
121     CODECHAL_DECODE_FUNCTION_ENTER;
122 #ifdef _MMC_SUPPORTED
123     // To WA invalid aux data caused HW issue when MMC on
124     // Add disable Clear CCS WA due to green corruption issue
125     if (m_mmc->IsMmcEnabled() && !Mos_ResourceIsNull(&m_destSurface.OsResource) &&
126         m_destSurface.OsResource.bConvertedFromDDIResource)
127     {
128         if (MEDIA_IS_WA(m_waTable, Wa_1408785368) || MEDIA_IS_WA(m_waTable, Wa_22010493002) && (!MEDIA_IS_WA(m_waTable, WaDisableClearCCS)))
129         {
130             CODECHAL_DECODE_VERBOSEMESSAGE("Clear CCS by VE resolve before frame %d submission", m_frameNum);
131             CODECHAL_DECODE_CHK_STATUS_RETURN(static_cast<CodecHalMmcStateG12 *>(m_mmc)->ClearAuxSurf(
132                 this, m_miInterface, &m_destSurface.OsResource, m_veState));
133         }
134     }
135 #endif
136 
137     MHW_VDBOX_JPEG_DECODE_PIC_STATE jpegPicState;
138     jpegPicState.dwOutputFormat = m_decodeParams.m_destSurface->Format;
139 
140 #ifdef _DECODE_PROCESSING_SUPPORTED
141     if (m_sfcState->m_sfcPipeOut)
142     {
143         jpegPicState.dwOutputFormat = m_sfcState->m_sfcInSurface.Format;
144     }
145 #endif
146 
147     //Three new formats from HSW C0,HSW ULT can only be supported in specific conditions.
148     if (jpegPicState.dwOutputFormat == Format_NV12 ||
149         jpegPicState.dwOutputFormat == Format_YUY2 ||
150         jpegPicState.dwOutputFormat == Format_UYVY)
151     {
152         //Only interleaved single scan are supported.
153         if (m_jpegPicParams->m_totalScans != 1 ||
154             m_jpegPicParams->m_interleavedData == 0)
155         {
156             return MOS_STATUS_UNKNOWN;
157         }
158 
159         switch (m_jpegPicParams->m_chromaType)
160         {
161         case jpegYUV420:
162         case jpegYUV422H2Y:
163         case jpegYUV422H4Y:
164             break;
165         case jpegYUV422V2Y:
166         case jpegYUV422V4Y:
167             if (jpegPicState.dwOutputFormat == Format_NV12)
168             {
169                 break;
170             }
171         default:
172             return MOS_STATUS_UNKNOWN;
173         }
174     }
175 
176     MOS_COMMAND_BUFFER cmdBuffer;
177     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
178         m_osInterface,
179         &cmdBuffer,
180         0));
181 
182     auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
183     HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
184 
185     MHW_MI_FORCE_WAKEUP_PARAMS forceWakeupParams;
186     MOS_ZeroMemory(&forceWakeupParams, sizeof(MHW_MI_FORCE_WAKEUP_PARAMS));
187     forceWakeupParams.bMFXPowerWellControl = true;
188     forceWakeupParams.bMFXPowerWellControlMask = true;
189     forceWakeupParams.bHEVCPowerWellControl = false;
190     forceWakeupParams.bHEVCPowerWellControlMask = true;
191     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiForceWakeupCmd(
192         &cmdBuffer,
193         &forceWakeupParams));
194 
195     CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
196         &cmdBuffer, true));
197 
198     // Set PIPE_MODE_SELECT
199     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
200     pipeModeSelectParams.Mode = CODECHAL_DECODE_MODE_JPEG;
201     pipeModeSelectParams.bStreamOutEnabled = m_streamOutEnabled;
202     pipeModeSelectParams.bDeblockerStreamOutEnable = false;
203     pipeModeSelectParams.bPostDeblockOutEnable = false;
204     pipeModeSelectParams.bPreDeblockOutEnable = true;
205 
206     // Set CMD_MFX_SURFACE_STATE
207     MHW_VDBOX_SURFACE_PARAMS surfaceParams;
208     MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
209     surfaceParams.Mode = CODECHAL_DECODE_MODE_JPEG;
210     surfaceParams.psSurface  = &m_destSurface;
211     surfaceParams.ChromaType = m_jpegPicParams->m_chromaType;
212 
213 #ifdef _DECODE_PROCESSING_SUPPORTED
214     if (m_sfcState->m_sfcPipeOut)
215     {
216         surfaceParams.psSurface = &m_sfcState->m_sfcInSurface;
217     }
218 #endif
219 
220     // Set MFX_PIPE_BUF_ADDR_STATE_CMD
221     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
222     pipeBufAddrParams.Mode = CODECHAL_DECODE_MODE_JPEG;
223     // Predeblock surface is the same as destination surface here because there is no deblocking for JPEG
224     pipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
225 
226 #ifdef _MMC_SUPPORTED
227     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&pipeBufAddrParams));
228 #endif
229 
230     // Set MFX_IND_OBJ_BASE_ADDR_STATE_CMD
231     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
232     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
233     indObjBaseAddrParams.Mode = CODECHAL_DECODE_MODE_JPEG;
234     indObjBaseAddrParams.dwDataSize     = m_copiedDataBufferInUse ? m_nextCopiedDataOffset : m_dataSize;
235     indObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
236 
237     // Set MFX_JPEG_PIC_STATE_CMD
238     jpegPicState.pJpegPicParams = m_jpegPicParams;
239     if ((m_jpegPicParams->m_rotation == jpegRotation90) || (m_jpegPicParams->m_rotation == jpegRotation270))
240     {
241         jpegPicState.dwWidthInBlocks  = (m_destSurface.dwHeight / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
242         jpegPicState.dwHeightInBlocks = (m_destSurface.dwWidth / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
243     }
244     else
245     {
246         jpegPicState.dwWidthInBlocks  = (m_destSurface.dwWidth / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
247         jpegPicState.dwHeightInBlocks = (m_destSurface.dwHeight / CODECHAL_DECODE_JPEG_BLOCK_SIZE) - 1;
248     }
249 
250     // Add commands to command buffer
251     // MI_FLUSH_DW command -> must be before to MFX_PIPE_MODE_SELECT
252     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
253     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
254     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
255         &cmdBuffer,
256         &flushDwParams));
257 
258     if (m_statusQueryReportingEnabled)
259     {
260         CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(
261             &cmdBuffer));
262     }
263 
264     // MFX_PIPE_MODE_SELECT_CMD
265     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(
266         &cmdBuffer,
267         &pipeModeSelectParams));
268 
269 #ifdef _DECODE_PROCESSING_SUPPORTED
270     // Output decode result through SFC
271     CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->AddSfcCommands(&cmdBuffer));
272 #endif
273 
274     // CMD_MFX_SURFACE_STATE
275 #ifdef _MMC_SUPPORTED
276     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetSurfaceState(&surfaceParams)); //class CodechalMmcDecodeJpegG12
277 #endif
278     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(
279         &cmdBuffer,
280         &surfaceParams));
281 
282     // MFX_PIPE_BUF_ADDR_STATE_CMD
283     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(
284         &cmdBuffer,
285         &pipeBufAddrParams));
286 
287     // MFX_IND_OBJ_BASE_ADDR_STATE_CMD
288     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(
289         &cmdBuffer,
290         &indObjBaseAddrParams));
291 
292     // MFX_JPEG_PIC_STATE_CMD
293     CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegPicCmd(
294         &cmdBuffer,
295         &jpegPicState));
296 
297     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
298 
299     return eStatus;
300 }
301 
DecodePrimitiveLevel()302 MOS_STATUS CodechalDecodeJpegG12::DecodePrimitiveLevel()
303 {
304     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
305 
306     CODECHAL_DECODE_FUNCTION_ENTER;
307 
308     // if the bitstream is not complete, don't do any decoding work.
309     if (m_incompletePicture)
310     {
311         return MOS_STATUS_SUCCESS;
312 
313     }
314 
315     CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
316 
317     MOS_COMMAND_BUFFER cmdBuffer;
318     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
319         m_osInterface,
320         &cmdBuffer,
321         0));
322 
323     // MFX_QM_STATE_CMD
324     MHW_VDBOX_QM_PARAMS qmParams;
325     MOS_ZeroMemory(&qmParams, sizeof(qmParams));
326     qmParams.Standard = CODECHAL_JPEG;
327     qmParams.pJpegQuantMatrix = m_jpegQMatrix;
328 
329     // Swapping QM(x,y) to QM(y,x) for 90/270 degree rotation
330     if ((m_jpegPicParams->m_rotation == jpegRotation90) ||
331         (m_jpegPicParams->m_rotation == jpegRotation270))
332     {
333         qmParams.bJpegQMRotation = true;
334     }
335     else
336     {
337         qmParams.bJpegQMRotation = false;
338     }
339 
340     for (uint16_t scanCount = 0; scanCount < m_jpegPicParams->m_numCompInFrame; scanCount++)
341     {
342         // Using scanCount here because the same command is used for JPEG decode and encode
343         uint32_t quantTableSelector                                      = m_jpegPicParams->m_quantTableSelector[scanCount];
344         if (quantTableSelector >= JPEG_MAX_NUM_OF_QUANTMATRIX)
345         {
346             CODECHAL_DECODE_ASSERTMESSAGE("Unsupported QuantTableSelector in JPEG Picture parameter.");
347             return MOS_STATUS_INVALID_PARAMETER;
348         }
349         qmParams.pJpegQuantMatrix->m_jpegQMTableType[quantTableSelector] = scanCount;
350         qmParams.JpegQMTableSelector = quantTableSelector;
351         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(
352             &cmdBuffer,
353             &qmParams));
354     }
355 
356     uint32_t dcCurHuffTblIndex[2] = { 0xff, 0xff };
357     uint32_t acCurHuffTblIndex[2] = { 0xff, 0xff };
358 
359     for (uint16_t scanCount = 0; scanCount < m_jpegScanParams->NumScans; scanCount++)
360     {
361         // MFX_JPEG_HUFF_TABLE
362         uint16_t numComponents = m_jpegScanParams->ScanHeader[scanCount].NumComponents;
363         for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
364         {
365             // Determine which huffman table we will be writing to
366             // For gray image, componentIdentifier[jpegComponentU] and componentIdentifier[jpegComponentV] are initialized to 0,
367             // and when componentSelector[scanComponent] is equal 0, variable huffTableID is set to 1, and wrong Huffman table is used,
368             // so it is more reasonable to use componentIdentifier[jpegComponentY] to determine which huffman table we will be writing to.
369             uint8_t componentSelector =
370                 m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
371             uint16_t huffTableID = 0;
372             if (componentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentY])
373             {
374                 huffTableID = 0;
375             }
376             else
377             {
378                 huffTableID = 1;
379             }
380 
381             int32_t acTableSelector =
382                 m_jpegScanParams->ScanHeader[scanCount].AcHuffTblSelector[scanComponent];
383             int32_t dcTableSelector =
384                 m_jpegScanParams->ScanHeader[scanCount].DcHuffTblSelector[scanComponent];
385 
386             // Send the huffman table state command only if the table changed
387             if ((dcTableSelector != dcCurHuffTblIndex[huffTableID]) ||
388                 (acTableSelector != acCurHuffTblIndex[huffTableID]))
389             {
390                 MHW_VDBOX_HUFF_TABLE_PARAMS huffmanTableParams;
391                 MOS_ZeroMemory(&huffmanTableParams, sizeof(huffmanTableParams));
392 
393                 huffmanTableParams.HuffTableID = huffTableID;
394                 if (acTableSelector >= JPEG_MAX_NUM_HUFF_TABLE_INDEX || dcTableSelector >= JPEG_MAX_NUM_HUFF_TABLE_INDEX)
395                     return MOS_STATUS_INVALID_PARAMETER;
396 
397                 huffmanTableParams.pACBits   = &m_jpegHuffmanTable->HuffTable[acTableSelector].AC_BITS[0];
398                 huffmanTableParams.pDCBits   = &m_jpegHuffmanTable->HuffTable[dcTableSelector].DC_BITS[0];
399                 huffmanTableParams.pACValues = &m_jpegHuffmanTable->HuffTable[acTableSelector].AC_HUFFVAL[0];
400                 huffmanTableParams.pDCValues = &m_jpegHuffmanTable->HuffTable[dcTableSelector].DC_HUFFVAL[0];
401 
402                 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegHuffTableCmd(
403                     &cmdBuffer,
404                     &huffmanTableParams));
405 
406                 // Set the current huffman table indices for the next scan
407                 dcCurHuffTblIndex[huffTableID] = dcTableSelector;
408                 acCurHuffTblIndex[huffTableID] = acTableSelector;
409             }
410         }
411 
412         MHW_VDBOX_JPEG_BSD_PARAMS jpegBsdObject;
413         MOS_ZeroMemory(&jpegBsdObject, sizeof(jpegBsdObject));
414 
415         // MFX_JPEG_BSD_OBJECT
416         jpegBsdObject.dwIndirectDataLength     = m_jpegScanParams->ScanHeader[scanCount].DataLength;
417         jpegBsdObject.dwDataStartAddress       = m_jpegScanParams->ScanHeader[scanCount].DataOffset;
418         jpegBsdObject.dwScanHorizontalPosition = m_jpegScanParams->ScanHeader[scanCount].ScanHoriPosition;
419         jpegBsdObject.dwScanVerticalPosition   = m_jpegScanParams->ScanHeader[scanCount].ScanVertPosition;
420         jpegBsdObject.bInterleaved = (numComponents > 1) ? 1 : 0;
421         jpegBsdObject.dwMCUCount               = m_jpegScanParams->ScanHeader[scanCount].MCUCount;
422         jpegBsdObject.dwRestartInterval        = m_jpegScanParams->ScanHeader[scanCount].RestartInterval;
423 
424         uint16_t scanComponentIndex = 0;
425 
426         for (uint16_t scanComponent = 0; scanComponent < numComponents; scanComponent++)
427         {
428             uint8_t componentSelector =
429                 m_jpegScanParams->ScanHeader[scanCount].ComponentSelector[scanComponent];
430 
431             if (componentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentY])
432             {
433                 scanComponentIndex = 0;
434             }
435             else if (componentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentU])
436             {
437                 scanComponentIndex = 1;
438             }
439             else if (componentSelector == m_jpegPicParams->m_componentIdentifier[jpegComponentV])
440             {
441                 scanComponentIndex = 2;
442             }
443             // Add logic for component identifier JPEG_A
444 
445             jpegBsdObject.sScanComponent |= (1 << scanComponentIndex);
446         }
447 
448         CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxJpegBsdObjCmd(
449             &cmdBuffer,
450             &jpegBsdObject));
451     }
452 
453     // Check if destination surface needs to be synchronized
454     MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
455     syncParams.GpuContext = m_videoContext;
456     syncParams.presSyncResource         = &m_destSurface.OsResource;
457     syncParams.bReadOnly = false;
458     syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
459     syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
460 
461     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(
462         m_osInterface,
463         &syncParams));
464     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(
465         m_osInterface,
466         &syncParams));
467 
468     // Update the resource tag (s/w tag) for On-Demand Sync
469     m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
470 
471     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
472     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
473     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
474         &cmdBuffer,
475         &flushDwParams));
476 
477     // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
478     if (m_osInterface->bTagResourceSync)
479     {
480         CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(
481             &cmdBuffer,
482             &syncParams));
483     }
484 
485     if (m_statusQueryReportingEnabled)
486     {
487         CodechalDecodeStatusReport decodeStatusReport;
488         decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
489         decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
490         decodeStatusReport.m_currDecodedPicRes  = m_destSurface.OsResource;
491 
492         CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(
493             decodeStatusReport,
494             &cmdBuffer));
495     }
496 
497 #if (_DEBUG || _RELEASE_INTERNAL)
498     uint32_t curIdx         = (GetDecodeStatusBuf()->m_currIndex + CODECHAL_DECODE_STATUS_NUM - 1) % CODECHAL_DECODE_STATUS_NUM;
499     uint32_t frameCrcOffset = curIdx * sizeof(CodechalDecodeStatus) + GetDecodeStatusBuf()->m_decFrameCrcOffset + sizeof(uint32_t) * 2;
500     std::vector<MOS_RESOURCE> vSemaResource{GetDecodeStatusBuf()->m_statusBuffer};
501     m_debugInterface->DetectCorruptionHw(m_hwInterface, &m_frameCountTypeBuf, curIdx, frameCrcOffset, vSemaResource, &cmdBuffer, m_frameNum);
502 #endif
503 
504     CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
505         &cmdBuffer,
506         nullptr));
507 
508     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
509 
510     CODECHAL_DEBUG_TOOL(
511         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
512             &cmdBuffer,
513             CODECHAL_NUM_MEDIA_STATES,
514             "_JPEG_DECODE_0"));
515     )
516 
517     if (m_copiedDataBufferInUse)
518     {
519         //Sync up complete frame
520         syncParams                  = g_cInitSyncParams;
521         syncParams.GpuContext       = m_videoContextForWa;
522         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
523 
524         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
525             m_osInterface,
526             &syncParams));
527 
528         syncParams                  = g_cInitSyncParams;
529         syncParams.GpuContext       = m_videoContext;
530         syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
531 
532         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
533             m_osInterface,
534             &syncParams));
535         }
536 
537     if ( MOS_VE_SUPPORTED(m_osInterface))
538     {
539         CodecHalDecodeSinglePipeVE_PopulateHintParams(m_veState, &cmdBuffer, false);
540     }
541 
542     HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
543 
544     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
545         m_osInterface,
546         &cmdBuffer,
547         m_videoContextUsesNullHw));
548 
549     CODECHAL_DEBUG_TOOL(
550         m_mmc->UpdateUserFeatureKey(&m_destSurface);)
551 
552     if (m_statusQueryReportingEnabled)
553     {
554         CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(
555             m_videoContextUsesNullHw));
556         }
557 
558     // Set output surface layout
559     SetOutputSurfaceLayout(&m_decodeParams.m_outputSurfLayout);
560 
561     // Send the signal to indicate decode completion, in case On-Demand Sync is not present
562     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(
563         m_osInterface,
564         &syncParams));
565 
566     CODECHAL_DEBUG_TOOL(
567         CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
568             &m_destSurface,
569             CodechalDbgAttr::attrDecodeOutputSurface,
570             "DstSurf"));)
571     return eStatus;
572 }
573 
AllocateStandard(CodechalSetting * settings)574 MOS_STATUS CodechalDecodeJpegG12::AllocateStandard(
575     CodechalSetting *          settings)
576 {
577     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
578 
579     CODECHAL_DECODE_FUNCTION_ENTER;
580 
581     CODECHAL_DECODE_CHK_NULL_RETURN(settings);
582 
583     CODECHAL_DECODE_CHK_STATUS_RETURN(CodechalDecodeJpeg::AllocateStandard(settings));
584 
585 #ifdef _MMC_SUPPORTED
586     // To WA invalid aux data caused HW issue when MMC on
587     // Add disable Clear CCS WA due to green corruption issue
588     if (m_mmc->IsMmcEnabled())
589     {
590         if (MEDIA_IS_WA(m_waTable, Wa_1408785368) || MEDIA_IS_WA(m_waTable, Wa_22010493002) && (!MEDIA_IS_WA(m_waTable, WaDisableClearCCS)))
591         {
592             MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
593 
594             //Add HUC STATE Commands
595             m_hwInterface->GetHucStateCommandSize(
596                 CODECHAL_DECODE_MODE_JPEG,
597                 &m_HucStateCmdBufferSizeNeeded,
598                 &m_HucPatchListSizeNeeded,
599                 &stateCmdSizeParams);
600         }
601     }
602 #endif
603 
604     if ( MOS_VE_SUPPORTED(m_osInterface))
605     {
606         static_cast<MhwVdboxMfxInterfaceG12*>(m_mfxInterface)->DisableScalabilitySupport();
607 
608         //single pipe VE initialize
609         m_veState = (PCODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE)MOS_AllocAndZeroMemory(sizeof(CODECHAL_DECODE_SINGLEPIPE_VIRTUALENGINE_STATE));
610         CODECHAL_DECODE_CHK_NULL_RETURN(m_veState);
611         CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalDecodeSinglePipeVE_InitInterface(m_osInterface, m_veState));
612     }
613 
614     return eStatus;
615 }
616 
CodechalDecodeJpegG12(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)617 CodechalDecodeJpegG12::CodechalDecodeJpegG12(
618     CodechalHwInterface   *hwInterface,
619     CodechalDebugInterface* debugInterface,
620     PCODECHAL_STANDARD_INFO standardInfo) :
621     CodechalDecodeJpeg(hwInterface, debugInterface, standardInfo)
622 {
623     CODECHAL_DECODE_FUNCTION_ENTER;
624 
625     CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_osInterface);
626 
627     m_osInterface->pfnVirtualEngineSupported(m_osInterface, true, true);
628 }
629 
CalcRequestedSpace(uint32_t & requestedSize,uint32_t & additionalSizeNeeded,uint32_t & requestedPatchListSize)630 void CodechalDecodeJpegG12::CalcRequestedSpace(
631     uint32_t &requestedSize,
632     uint32_t &additionalSizeNeeded,
633     uint32_t &requestedPatchListSize)
634 {
635     CODECHAL_DECODE_FUNCTION_ENTER;
636 
637     requestedSize = m_commandBufferSizeNeeded + m_HucStateCmdBufferSizeNeeded +
638                     (m_standardDecodeSizeNeeded * (m_decodeParams.m_numSlices + 1));
639     requestedPatchListSize = m_commandPatchListSizeNeeded + m_HucPatchListSizeNeeded +
640                              (m_standardDecodePatchListSizeNeeded * (m_decodeParams.m_numSlices + 1));
641     additionalSizeNeeded = COMMAND_BUFFER_RESERVED_SPACE;
642 }
643 
644