1 /*
2 * Copyright (c) 2019, 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     mos_gpucontext_specific.h
24 //! \brief    Container class for the linux/Android specfic gpu context
25 //!
26 
27 #ifndef __GPU_CONTEXT_SPECIFIC_NEXT_H__
28 #define __GPU_CONTEXT_SPECIFIC_NEXT_H__
29 
30 #include "mos_gpucontext_next.h"
31 #include "mos_graphicsresource_specific_next.h"
32 #include "mos_oca_interface_specific.h"
33 
34 #define ENGINE_INSTANCE_SELECT_ENABLE_MASK                   0xFF
35 #define ENGINE_INSTANCE_SELECT_COMPUTE_INSTANCE_SHIFT        16
36 #define ENGINE_INSTANCE_SELECT_VEBOX_INSTANCE_SHIFT          8
37 #define ENGINE_INSTANCE_SELECT_VDBOX_INSTANCE_SHIFT          0
38 
39 //!
40 //! \class  GpuContextSpecific
41 //! \brief  Linux/Android specific gpu context
42 //!
43 class GpuContextSpecificNext : public GpuContextNext
44 {
45 public:
46     //!
47     //! \brief  Constructor
48     //!
49     GpuContextSpecificNext(
50         const MOS_GPU_NODE gpuNode,
51         CmdBufMgrNext      *cmdBufMgr,
52         GpuContextNext    *reusedContext);
53 
54     //!
55     //! \brief  Destructor
56     //!
57     ~GpuContextSpecificNext();
58 
59     //!
60     //! \brief    Static entrypoint, get the gpu context object
61     //! \param    [in] gpuNode
62     //!           Gpu node
63     //! \param    [in] cmdBufMgr
64     //!           Command buffer manager
65     //! \param    [in] reusedContext
66     //!           Reused gpu context
67     //! \return   GpuContextNext*
68     //!           the os specific object for gpu context
69     //!
70     static GpuContextNext* Create(
71         const MOS_GPU_NODE gpuNode,
72         CmdBufMgrNext      *cmdBufMgr,
73         GpuContextNext     *reusedContext);
74 
75     //!
76     //! \brief    Initialize gpu context
77     //! \details  Linux specific initialize for gpu context
78     //! \param    [in] osContext
79     //!           MOS device context pointer
80     //! \param    [in] streamState
81     //!           Os stream state
82     //! \param    [in] createOption
83     //!           Create option of creating GPU context
84     //! \return   MOS_STATUS
85     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
86     //!
87     virtual MOS_STATUS Init(OsContextNext *osContext,
88                     MOS_STREAM_HANDLE streamState,
89                     PMOS_GPUCTX_CREATOPTIONS createOption);
90 
91     void Clear(void);
92 
93     //!
94     //! \brief    Recreate GPU context as protected or clear if needed
95     //! \param    [in] streamState
96     //!           Os stream state
97     //! \return   MOS_STATUS
98     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
99     //!
100     MOS_STATUS PatchGPUContextProtection(MOS_STREAM_HANDLE streamState);
101 
102     //!
103     //! \brief    Register graphics resource
104     //! \details  Set the Allocation Index in OS resource structure
105     //! \param    [out] osContext
106     //!           Os context pointer
107     //! \param    [in] writeFlag
108     //!           Write Flag
109     //! \return   MOS_STATUS
110     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
111     //!
112     MOS_STATUS RegisterResource(
113         PMOS_RESOURCE osResource,
114         bool          writeFlag);
115 
116     MOS_STATUS GetCommandBuffer(
117         PMOS_COMMAND_BUFFER comamndBuffer,
118         uint32_t            flags);
119 
VerifyCommandBufferSize(const uint32_t requestedSize)120     MOS_STATUS VerifyCommandBufferSize(const uint32_t requestedSize)
121     {
122         return m_ocaLogSectionSupported ?
123                ((m_commandBufferSize < MosOcaInterfaceSpecific::IncreaseSize(requestedSize)) ? MOS_STATUS_UNKNOWN:MOS_STATUS_SUCCESS) :
124                ((m_commandBufferSize < requestedSize) ? MOS_STATUS_UNKNOWN:MOS_STATUS_SUCCESS);
125     }
126 
127     MOS_STATUS GetIndirectState(
128         uint32_t &offset,
129         uint32_t &size);
130 
131     MOS_STATUS GetIndirectStatePointer(
132         uint8_t **indirectState);
133 
134     MOS_STATUS SetIndirectStateSize(const uint32_t size);
135 
136     //!
137     //! \brief    Set patch entry
138     //! \details  Sets the patch entry in patch list
139     //! \param    [in] streamState
140     //!           OS steam state
141     //! \param    [in] params
142     //!           patch entry params
143     //! \return   MOS_STATUS
144     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
145     //!
146     MOS_STATUS SetPatchEntry(
147         MOS_STREAM_HANDLE streamState,
148         PMOS_PATCH_ENTRY_PARAMS params);
149 
150     void ReturnCommandBuffer(
151         PMOS_COMMAND_BUFFER cmdBuffer,
152         uint32_t            flags);
153 
154     //!
155     //! \brief    reset command buffer space
156     //! \details  resets the command buffer space
157     //! \return   MOS_STATUS
158     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
159     //!
160     MOS_STATUS ResetCommandBuffer();
161 
162     //!
163     //! \brief    Verifys the patch list to be used for rendering GPU commands is large enough
164     //! \param    [in] requestedSize
165     //!           Patch list size to be verified
166     //! \return   MOS_STATUS
167     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
168     //!
VerifyPatchListSize(const uint32_t requestedSize)169     MOS_STATUS VerifyPatchListSize(const uint32_t requestedSize)
170     {
171         return (requestedSize > m_maxPatchLocationsize) ? MOS_STATUS_UNKNOWN : MOS_STATUS_SUCCESS;
172     }
173 
174     MOS_STATUS SubmitCommandBuffer(
175         MOS_STREAM_HANDLE   streamState,
176         PMOS_COMMAND_BUFFER cmdBuffer,
177         bool                nullRendering);
178 
179     MOS_STATUS ResizeCommandBufferAndPatchList(
180         uint32_t requestedCommandBufferSize,
181         uint32_t requestedPatchListSize,
182         uint32_t flags);
183 
184     //!
185     //! \brief    Resizes the buffer to be used for rendering GPU commands
186     //! \param    [in] requestedSize
187     //!           Requested size
188     //! \return   MOS_STATUS
189     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
190     //!
191     MOS_STATUS ResizeCommandBuffer(uint32_t requestedSize);
192 
193     //!
194     //! \brief    Get GPU status tag
195     //! \details  Gets the status tag
196     //! \return   uint32_t
197     //!           Returns the tag
198     //!
GetGpuStatusTag()199     uint32_t   GetGpuStatusTag() { return m_GPUStatusTag; }
200 
201     //!
202     //! \brief    Get i915 ctx
203     //! \param    [in] ctxNodeIndex
204     //!           ctx index in array
205     //! \return   MOS_LINUX_CONTEXT
206     //!           mos linux ctx in array of ctxNodeIndex
207     //!
GetI915Context(uint32_t ctxNodeIndex)208     MOS_LINUX_CONTEXT* GetI915Context(uint32_t ctxNodeIndex){return ctxNodeIndex < (MAX_ENGINE_INSTANCE_NUM+1) ?  m_i915Context[ctxNodeIndex] : nullptr;}
209 
210     //!
211     //! \brief    Increment GPU status tag
212     //!
213     void       IncrementGpuStatusTag();
214 
215     void       ResetGpuContextStatus();
216 
217     //!
218     //! \brief  Set the Gpu priority for workload scheduling.
219     //! \param [in] priority
220     //!             priority to set for current workload.
221     //! \return void
222     //!
223     virtual void UpdatePriority(int32_t priority);
224 
225     //!
226     //! \brief    Allocate gpu status buffer for gpu sync
227     //! \return   MOS_STATUS
228     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
229     //!
230     MOS_STATUS AllocateGPUStatusBuf();
231 
232     //!
233     //! \brief    Store create options to member variable
234     //! \return   void
235     //!
236     void StoreCreateOptions(PMOS_GPUCTX_CREATOPTIONS createoption);
237 
238     //!
239     //! \brief    Get Oca RTLog resource instance on GPU Context.
240     //! \return   PMOS_RESOURCE
241     //!
242     PMOS_RESOURCE GetOcaRTLogResource(PMOS_RESOURCE globalInst);
243 
244 #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
PushCmdResPtr(const void * p)245     void                PushCmdResPtr(const void *p) { m_cmdResPtrs.push_back(p); }
ClearCmdResPtrs()246     void                ClearCmdResPtrs() { m_cmdResPtrs.clear(); }
GetCmdResPtrs()247     const std::vector<const void *> &GetCmdResPtrs() const { return m_cmdResPtrs; }
248 #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
249 protected:
250     virtual MOS_STATUS Init3DCtx(PMOS_CONTEXT osParameters,
251                 PMOS_GPUCTX_CREATOPTIONS createOption,
252                 unsigned int *nengine,
253                 void *engine_map);
254 
255     virtual MOS_STATUS InitComputeCtx(PMOS_CONTEXT osParameters,
256                 unsigned int *nengine,
257                 void *engine_map,
258                 MOS_GPU_NODE gpuNode,
259                 bool *isEngineSelectEnable);
260 
261     virtual MOS_STATUS InitVdVeCtx(PMOS_CONTEXT osParameters,
262                 MOS_STREAM_HANDLE streamState,
263                 PMOS_GPUCTX_CREATOPTIONS createOption,
264                 unsigned int *nengine,
265                 void *engine_map,
266                 MOS_GPU_NODE gpuNode,
267                 bool *isEngineSelectEnable);
268 
269     virtual MOS_STATUS InitBltCtx(PMOS_CONTEXT osParameters,
270                 unsigned int *nengine,
271                 void *engine_map);
272 
273     //!
274     //! \brief    Map resources with aux plane to aux table
275     //! \return   MOS_STATUS
276     //!           Return MOS_STATUS_SUCCESS if successful, otherwise failed
277     //!
278     MOS_STATUS MapResourcesToAuxTable(mos_linux_bo *cmd_bo);
279 
280     MOS_VDBOX_NODE_IND GetVdboxNodeId(
281         PMOS_COMMAND_BUFFER cmdBuffer);
282 
283     uint32_t GetVcsExecFlag(
284         PMOS_COMMAND_BUFFER cmdBuffer,
285         MOS_GPU_NODE gpuNode);
286 
287     //!
288     //! \brief    Submit command buffer for single pipe in scalability mode
289     //! \return   int32_t
290     //!           Return 0 if successful, otherwise error code
291     //!
292     int32_t SubmitPipeCommands(MOS_COMMAND_BUFFER *cmdBuffer,
293                                MOS_LINUX_BO *cmdBo,
294                                PMOS_CONTEXT osContext,
295                                const std::vector<MOS_LINUX_BO *> &skipSyncBoList,
296                                uint32_t execFlag,
297                                int32_t dr4);
298 
299     //!
300     //! \brief    Combin cmd buffer for each pipe and use one submission  in scalability mode
301     //! \return   int32_t
302     //!           Return 0 if successful, otherwise error code
303     //!
304     virtual int32_t ParallelSubmitCommands(std::map<uint32_t, PMOS_COMMAND_BUFFER> secondaryCmdBufs,
305                                    PMOS_CONTEXT osContext,
306                                    uint32_t execFlag,
307                                    int32_t dr4);
308 
309     //!
310     //! \brief    Set the flags of engin quering according to create options
311     //! \return   void
312     //!
313     void SetEngineQueryFlags(
314         PMOS_GPUCTX_CREATOPTIONS option,
315         __u64 &caps);
316 
317     virtual MOS_STATUS ReportEngineInfo(
318         void *engine_map,
319         int engineNum, bool engineSelectEnable = false);
320 
321     MOS_STATUS ReportMemoryInfo(
322         struct mos_bufmgr *bufmgr);
323 
324 #if (_DEBUG || _RELEASE_INTERNAL)
325     MOS_LINUX_BO* GetNopCommandBuffer(
326         MOS_STREAM_HANDLE streamState);
327 
328     virtual bool SelectEngineInstanceByUser(void *engine_map,
329         uint32_t *engineNum, uint32_t userEngineInstance, MOS_GPU_NODE gpuNode);
330 #endif // _DEBUG || _RELEASE_INTERNAL
331 
332     void UnlockPendingOcaBuffers(PMOS_COMMAND_BUFFER cmdBuffer, PMOS_CONTEXT mosContext);
333 
334 protected:
335     //! \brief    internal command buffer pool per gpu context
336     std::vector<CommandBufferNext *> m_cmdBufPool;
337 
338     //! \brief    internal command buffer pool per gpu context
339     PMOS_MUTEX m_cmdBufPoolMutex = nullptr;
340 
341     //! \brief    next fetch index of m_cmdBufPool
342     uint32_t m_nextFetchIndex = 0;
343 
344     //! \brief    initialized comamnd buffer size
345     uint32_t m_commandBufferSize = 0;
346 
347     //! \brief    Flag to indicate current command buffer flused or not, if not
348     //!           re-use it
349     volatile bool m_cmdBufFlushed = false;
350 
351     //! \brief    internal back up for in-use command buffer
352     PMOS_COMMAND_BUFFER m_commandBuffer = nullptr;
353 
354     //! \brief    secondary command buffers for scalability
355     std::map<uint32_t, PMOS_COMMAND_BUFFER> m_secondaryCmdBufs;
356 
357     //! \brief    Allcoation List related struct
358     ALLOCATION_LIST *m_allocationList = nullptr;
359     uint32_t         m_numAllocations = 0;  //!< number of registered allocation list
360     uint32_t         m_maxNumAllocations = 0;  //!< max number of allocation list
361 
362     //! \brief    Pathc List related struct
363     PATCHLOCATIONLIST *m_patchLocationList = nullptr;
364     uint32_t           m_currentNumPatchLocations = 0; //!< number of registered patch list
365     uint32_t           m_maxPatchLocationsize; //!< max number of patch list
366 
367    //! \brief    Resource registrations
368     uint32_t      m_resCount = 0;  //!< number of resources registered
369     PMOS_RESOURCE m_attachedResources = nullptr;  //!< Pointer to resources list
370     bool         *m_writeModeList     = nullptr;  //!< Write mode
371 
372     //! \brief    GPU Status tag
373     uint32_t m_GPUStatusTag = 0;
374 
375     //! \brief    Os context
376     OsContextNext *m_osContext      = nullptr;
377 
378     //! \brief    mos context
379     PMOS_CONTEXT  m_osParameters    = nullptr;
380 
381     MOS_GPUCTX_CREATOPTIONS_ENHANCED m_createOptionEnhanced;            //!< stores create otpions if user is using MOS_GPUCTX_CREATOPTIONS_ENHANCED
382     MOS_GPUCTX_CREATOPTIONS          m_createOption;                    //!< stores create otpions if user is using MOS_GPUCTX_CREATOPTIONS
383     bool                             m_bEnhancedUsed        = false;    //!< true if caller is using MOS_GPUCTX_CREATOPTIONS_ENHANCED,
384                                                                         //!< false if using MOS_GPUCTX_CREATOPTIONS
385     bool                             m_bProtectedContext    = false;    //!< false if clear GEM context is created as protected or not
386 
387     MOS_LINUX_CONTEXT*  m_i915Context[MAX_ENGINE_INSTANCE_NUM+1] = {};
388     uint32_t     m_i915ExecFlag = 0;
389     int32_t      m_currCtxPriority = 0;
390     bool m_ocaLogSectionSupported = true;
391     // bool m_ocaSizeIncreaseDone = false;
392 
393     bool m_ocaRtLogResInited = false;
394     MOS_RESOURCE m_ocaRtLogResource = {};
395     //! \brief Recreate GEM Context
396     //! \return   MOS_STATUS
397     //!           Return MOS_STATUS_SUCCESS if successful, otherwise error code
398     //!
399     MOS_STATUS RecreateContext(bool bIsProtected, MOS_STREAM_HANDLE streamState);
400 
401 #if (_DEBUG || _RELEASE_INTERNAL)
402     /*!\brief bits(23...16), (15...8), (7...0) are for Compute, VEbox and VDbox ;
403     single or multi engine instance can be selected at same time(0x10103 to select Compute1, VE1, VD1&VD2 for example)*/
404     uint32_t m_engineInstanceSelect = 0x0;
405 #endif
406 
407 #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED
408     std::vector<const void *> m_cmdResPtrs; //!< Command OS resource pointers registered by pfnRegisterResource
409 #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED
410 MEDIA_CLASS_DEFINE_END(GpuContextSpecificNext)
411 };
412 #endif  // __GPU_CONTEXT_SPECIFIC_NEXT_H__
413