1 /*
2 * Copyright (c) 2019-2021, 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 frame_tracker.cpp
24 //! \brief Manages the multiple trackers in one place.
25 //!
26
27 #include "frame_tracker.h"
28 #include "mhw_utilities.h"
29 #include "mos_interface.h"
30
FrameTrackerTokenFlat_IsExpired(const FrameTrackerTokenFlat * self)31 bool FrameTrackerTokenFlat_IsExpired(const FrameTrackerTokenFlat *self)
32 {
33 if (self->stick)
34 {
35 return false;
36 }
37 if (self->producer == nullptr)
38 {
39 return true;
40 }
41 for (int i = 0; i < MAX_TRACKER_NUMBER; i ++)
42 {
43 if (self->trackers[i] != 0)
44 {
45 volatile uint32_t latestTracker = *(self->producer->GetLatestTrackerAddress(i));
46 if ((int)(self->trackers[i] - latestTracker) > 0)
47 {
48 return false;
49 }
50 }
51 }
52 return true;
53 }
54
Merge(const FrameTrackerToken * token)55 void FrameTrackerToken::Merge(const FrameTrackerToken *token)
56 {
57 m_producer = token->m_producer;
58 for (auto ite = token->m_holdTrackers.begin(); ite != token->m_holdTrackers.end(); ite ++)
59 {
60 uint32_t index = ite->first;
61 uint32_t holdTracker = ite->second;
62 Merge(index, holdTracker);
63 }
64 }
65
FrameTrackerProducer()66 FrameTrackerProducer::FrameTrackerProducer():
67 m_nextTrackerIndex(0),
68 m_resourceData(nullptr),
69 m_osInterface(nullptr)
70 {
71 MOS_ZeroMemory(&m_resource, sizeof(MOS_RESOURCE));
72 MOS_ZeroMemory(m_trackerInUse, sizeof(m_trackerInUse));
73 MOS_ZeroMemory(m_counters, sizeof(m_counters));
74 }
75
~FrameTrackerProducer()76 FrameTrackerProducer::~FrameTrackerProducer()
77 {
78 MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
79
80 resFreeFlags.AssumeNotInUse = 1;
81
82 if (!Mos_ResourceIsNull(&m_resource))
83 {
84 m_osInterface->pfnUnlockResource(
85 m_osInterface,
86 &m_resource);
87
88 m_osInterface->pfnFreeResourceWithFlag(
89 m_osInterface,
90 &m_resource,
91 resFreeFlags.Value);
92 }
93 }
94
Initialize(MOS_INTERFACE * osInterface)95 MOS_STATUS FrameTrackerProducer::Initialize(MOS_INTERFACE *osInterface)
96 {
97 m_osInterface = osInterface;
98 MHW_CHK_NULL_RETURN(m_osInterface);
99
100 m_osInterface->pfnResetResource(&m_resource);
101 // allocate the resource
102 MOS_ALLOC_GFXRES_PARAMS allocParamsLinearBuffer;
103 uint32_t size = MOS_ALIGN_CEIL(MAX_TRACKER_NUMBER * m_trackerSize, MHW_CACHELINE_SIZE);
104 MOS_ZeroMemory(&allocParamsLinearBuffer, sizeof(MOS_ALLOC_GFXRES_PARAMS));
105 allocParamsLinearBuffer.Type = MOS_GFXRES_BUFFER;
106 allocParamsLinearBuffer.TileType = MOS_TILE_LINEAR;
107 allocParamsLinearBuffer.Format = Format_Buffer;
108 allocParamsLinearBuffer.dwBytes = size;
109 allocParamsLinearBuffer.pBufName = "FrameTrackerResource";
110
111 MHW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
112 m_osInterface,
113 &allocParamsLinearBuffer,
114 &m_resource));
115
116 // RegisterResource will be called in AddResourceToHWCmd. It is not allowed to be called by hal explicitly
117 if (!m_osInterface->apoMosEnabled)
118 {
119 MHW_CHK_STATUS_RETURN(
120 m_osInterface->pfnRegisterResource(m_osInterface, &m_resource, true, true));
121 }
122
123 // Lock the Resource
124 MOS_LOCK_PARAMS lockFlags;
125 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
126 lockFlags.ReadOnly = 1;
127 lockFlags.ForceCached = true;
128
129 m_resourceData = (uint32_t*)m_osInterface->pfnLockResource(
130 m_osInterface,
131 &m_resource,
132 &lockFlags);
133 MOS_ZeroMemory(m_resourceData, size);
134
135 m_osInterface->pfnSkipResourceSync(&m_resource);
136
137 MHW_CHK_NULL_RETURN(m_resourceData);
138
139 return MOS_STATUS_SUCCESS;
140 }
141
AssignNewTracker()142 int FrameTrackerProducer::AssignNewTracker()
143 {
144 uint32_t trackerIndex = m_nextTrackerIndex;
145 bool found = false;
146 do
147 {
148 if (!m_trackerInUse[trackerIndex])
149 {
150 found = true;
151 break;
152 }
153 else
154 {
155 ++ trackerIndex;
156 if (trackerIndex == MAX_TRACKER_NUMBER)
157 {
158 trackerIndex = 0;
159 }
160 }
161 }
162 while (trackerIndex != m_nextTrackerIndex);
163
164 if (found)
165 {
166 m_trackerInUse[trackerIndex] = true;
167 m_counters[trackerIndex] = 1;
168 m_nextTrackerIndex = trackerIndex + 1;
169 if (m_nextTrackerIndex == MAX_TRACKER_NUMBER)
170 {
171 m_nextTrackerIndex = 0;
172 }
173
174 return trackerIndex;
175 }
176 else
177 {
178 return -1;
179 }
180 }
181