1 /*
2 * Copyright (c) 2022, 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 //!
24 //! \file     decode_scalability_singlepipe_next.cpp
25 //! \brief    Defines the common interface for media scalability singlepipe mode.
26 //! \details  The media scalability singlepipe interface is further sub-divided by component,
27 //!           this file is for the base interface which is shared by all components.
28 //!
29 
30 #include "codec_hw_next.h"
31 #include "decode_scalability_defs.h"
32 #include "decode_scalability_singlepipe_next.h"
33 
34 #include "media_context.h"
35 #include "media_status_report.h"
36 #include "mhw_utilities.h"
37 #include "decode_status_report_defs.h"
38 
39 namespace decode
40 {
41 
DecodeScalabilitySinglePipeNext(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)42 DecodeScalabilitySinglePipeNext::DecodeScalabilitySinglePipeNext(void *hwInterface, MediaContext *mediaContext, uint8_t componentType) :
43     MediaScalabilitySinglePipeNext(hwInterface, mediaContext, componentType)
44 {
45     if (hwInterface == nullptr)
46     {
47         return;
48     }
49     m_hwInterface = (CodechalHwInterfaceNext *)hwInterface;
50     m_osInterface = m_hwInterface->GetOsInterface();
51 }
52 
Initialize(const MediaScalabilityOption & option)53 MOS_STATUS DecodeScalabilitySinglePipeNext::Initialize(const MediaScalabilityOption &option)
54 {
55     SCALABILITY_CHK_NULL_RETURN(m_osInterface);
56 
57     DecodeScalabilityOption *decodeScalabilityOption = MOS_New(DecodeScalabilityOption, (const DecodeScalabilityOption &)option);
58     SCALABILITY_CHK_NULL_RETURN(decodeScalabilityOption);
59     m_scalabilityOption = decodeScalabilityOption;
60 
61     m_frameTrackingEnabled = m_osInterface->bEnableKmdMediaFrameTracking ? true : false;
62 
63     // !Don't check the return status here, because this function will return fail if there's no regist key in register.
64     // But it's normal that regist key not in register.
65     m_osInterface->pfnVirtualEngineSupported(m_osInterface, false, true);
66     m_miItf = m_hwInterface->GetMiInterfaceNext();
67     SCALABILITY_CHK_NULL_RETURN(m_miItf);
68 
69     SCALABILITY_CHK_STATUS_RETURN(MediaScalabilitySinglePipeNext::Initialize(option));
70     PMOS_GPUCTX_CREATOPTIONS_ENHANCED gpuCtxCreateOption = dynamic_cast<PMOS_GPUCTX_CREATOPTIONS_ENHANCED>(m_gpuCtxCreateOption);
71     SCALABILITY_CHK_NULL_RETURN(gpuCtxCreateOption);
72     gpuCtxCreateOption->UsingSFC = decodeScalabilityOption->IsUsingSFC();
73     if (decodeScalabilityOption->IsUsingSlimVdbox())
74     {
75         gpuCtxCreateOption->Flags |=  (1 << 2);
76     }
77 
78     return MOS_STATUS_SUCCESS;
79 }
80 
VerifyCmdBuffer(uint32_t requestedSize,uint32_t requestedPatchListSize,bool & singleTaskPhaseSupportedInPak)81 MOS_STATUS DecodeScalabilitySinglePipeNext::VerifyCmdBuffer(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
82 {
83     SCALABILITY_FUNCTION_ENTER;
84 
85     return MediaScalabilitySinglePipeNext::VerifyCmdBuffer(requestedSize, requestedPatchListSize, singleTaskPhaseSupportedInPak);
86 }
87 
VerifySpaceAvailable(uint32_t requestedSize,uint32_t requestedPatchListSize,bool & singleTaskPhaseSupportedInPak)88 MOS_STATUS DecodeScalabilitySinglePipeNext::VerifySpaceAvailable(uint32_t requestedSize, uint32_t requestedPatchListSize, bool &singleTaskPhaseSupportedInPak)
89 {
90     SCALABILITY_FUNCTION_ENTER;
91 
92     uint8_t looptimes = 3;
93     for(auto i = 0 ; i < looptimes ; i++)
94     {
95         bool bothPatchListAndCmdBufChkSuccess = false;
96         SCALABILITY_CHK_STATUS_RETURN(MediaScalability::VerifySpaceAvailable(
97             requestedSize, requestedPatchListSize, bothPatchListAndCmdBufChkSuccess));
98 
99         if (bothPatchListAndCmdBufChkSuccess)
100         {
101             return MOS_STATUS_SUCCESS;
102         }
103 
104         MOS_STATUS statusPatchList = MOS_STATUS_SUCCESS;
105         if (requestedPatchListSize > 0)
106         {
107             statusPatchList = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
108                 m_osInterface,
109                 requestedPatchListSize);
110         }
111 
112         MOS_STATUS statusCmdBuf = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
113             m_osInterface,
114             requestedSize,
115             0);
116 
117         if (statusCmdBuf == MOS_STATUS_SUCCESS && statusPatchList == MOS_STATUS_SUCCESS)
118         {
119             return MOS_STATUS_SUCCESS;
120         }
121     }
122 
123     SCALABILITY_ASSERTMESSAGE("Resize Command buffer failed with no space!");
124     return MOS_STATUS_NO_SPACE;
125 }
126 
UpdateState(void * statePars)127 MOS_STATUS DecodeScalabilitySinglePipeNext::UpdateState(void *statePars)
128 {
129     SCALABILITY_FUNCTION_ENTER;
130     SCALABILITY_CHK_NULL_RETURN(statePars);
131 
132     SCALABILITY_CHK_STATUS_RETURN(MediaScalabilitySinglePipeNext::UpdateState(statePars));
133 
134     StateParams *stateParams     = (StateParams *)statePars;
135     m_singleTaskPhaseSupported   = stateParams->singleTaskPhaseSupported;
136     m_statusReport               = stateParams->statusReport;
137     m_currentPass                = stateParams->currentPass;
138     m_componentState             = stateParams->componentState;
139     SCALABILITY_CHK_NULL_RETURN(m_statusReport);
140 
141     return MOS_STATUS_SUCCESS;
142 }
143 
ResizeCommandBufferAndPatchList(uint32_t requestedCommandBufferSize,uint32_t requestedPatchListSize)144 MOS_STATUS DecodeScalabilitySinglePipeNext::ResizeCommandBufferAndPatchList(
145     uint32_t                    requestedCommandBufferSize,
146     uint32_t                    requestedPatchListSize)
147 {
148     SCALABILITY_FUNCTION_ENTER;
149     SCALABILITY_CHK_NULL_RETURN(m_hwInterface);
150 
151     return m_hwInterface->ResizeCommandBufferAndPatchList(requestedCommandBufferSize, requestedPatchListSize);
152 }
153 
SendAttrWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)154 MOS_STATUS DecodeScalabilitySinglePipeNext::SendAttrWithFrameTracking(
155     MOS_COMMAND_BUFFER &cmdBuffer,
156     bool                frameTrackingRequested)
157 {
158     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
159 
160     SCALABILITY_FUNCTION_ENTER;
161 
162     bool renderEngineUsed = m_mediaContext->IsRenderEngineUsed();
163 
164     // initialize command buffer attributes
165     cmdBuffer.Attributes.bTurboMode               = m_hwInterface->m_turboMode;
166     cmdBuffer.Attributes.bMediaPreemptionEnabled  = renderEngineUsed ? m_hwInterface->GetRenderInterfaceNext()->IsPreemptionEnabled() : 0;
167 
168     if (frameTrackingRequested && m_frameTrackingEnabled)
169     {
170         PMOS_RESOURCE resource = nullptr;
171         uint32_t      offset   = 0;
172         m_statusReport->GetAddress(decode::statusReportGlobalCount, resource, offset);
173 
174         cmdBuffer.Attributes.bEnableMediaFrameTracking    = true;
175         cmdBuffer.Attributes.resMediaFrameTrackingSurface = resource;
176         cmdBuffer.Attributes.dwMediaFrameTrackingTag      = m_statusReport->GetSubmittedCount() + 1;
177         // Set media frame tracking address offset(the offset from the decoder status buffer page)
178         cmdBuffer.Attributes.dwMediaFrameTrackingAddrOffset = offset;
179     }
180 
181     return eStatus;
182 }
183 
CreateDecodeSinglePipe(void * hwInterface,MediaContext * mediaContext,uint8_t componentType)184 MOS_STATUS DecodeScalabilitySinglePipeNext::CreateDecodeSinglePipe(void *hwInterface, MediaContext *mediaContext, uint8_t componentType)
185 {
186     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
187 
188     SCALABILITY_FUNCTION_ENTER;
189 
190     SCALABILITY_CHK_NULL_RETURN(hwInterface);
191     SCALABILITY_CHK_NULL_RETURN(mediaContext);
192 
193     ((CodechalHwInterfaceNext *)hwInterface)->m_singlePipeScalability = MOS_New(DecodeScalabilitySinglePipeNext, hwInterface, mediaContext, scalabilityDecoder);
194     SCALABILITY_CHK_NULL_RETURN(((CodechalHwInterfaceNext *)hwInterface)->m_singlePipeScalability);
195 
196     return eStatus;
197 }
198 
199 }
200 
201 
202