1 /*
2 * Copyright (c) 2018, 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 media_cmd_task.cpp
25 //! \brief Defines the interface for media cmd task
26 //! \details The media cmd task is dedicated for command buffer submission
27 //!
28 #include <stdint.h>
29 #include <memory>
30 #include <vector>
31 #include "media_scalability.h"
32 #include "media_scalability_defs.h"
33 #include "mos_utilities.h"
34 #include "media_cmd_task.h"
35 #include "media_packet.h"
36 #include "media_utils.h"
37
CmdTask(PMOS_INTERFACE osInterface)38 CmdTask::CmdTask(PMOS_INTERFACE osInterface)
39 : m_osInterface(osInterface)
40 {
41
42 }
43
CalculateCmdBufferSizeFromActivePackets()44 MOS_STATUS CmdTask::CalculateCmdBufferSizeFromActivePackets()
45 {
46 uint32_t curCommandBufferSize = 0;
47 uint32_t curRequestedPatchListSize = 0;
48
49 m_cmdBufSize = 0;
50 m_patchListSize = 0;
51 for (auto prop : m_packets)
52 {
53 // Calculate total size based on pipe 0
54 if (prop.stateProperty.currentPipe == 0)
55 {
56 auto packetId = prop.packetId;
57 auto packet = prop.packet;
58
59 MEDIA_CHK_NULL_RETURN(packet);
60
61 curCommandBufferSize = 0;
62 curRequestedPatchListSize = 0;
63
64 packet->CalculateCommandSize(curCommandBufferSize, curRequestedPatchListSize);
65 m_cmdBufSize += curCommandBufferSize;
66 m_patchListSize += curRequestedPatchListSize;
67 }
68 }
69
70 return MOS_STATUS_SUCCESS;
71 }
72
Submit(bool immediateSubmit,MediaScalability * scalability,CodechalDebugInterface * debugInterface)73 MOS_STATUS CmdTask::Submit(bool immediateSubmit, MediaScalability *scalability, CodechalDebugInterface *debugInterface)
74 {
75 MEDIA_CHK_NULL_RETURN(scalability);
76
77 // Algin this variable in pipeline, packet and scalability.
78 bool singleTaskPhaseSupportedInPak = false;
79 MEDIA_CHK_STATUS_RETURN(CalculateCmdBufferSizeFromActivePackets());
80
81 // prepare cmd buffer
82 MOS_COMMAND_BUFFER cmdBuffer;
83 // initialize the command buffer struct
84 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
85
86 if (m_packets.size() > 0)
87 {
88 MEDIA_CHK_STATUS_RETURN(scalability->UpdateState(&m_packets[0].stateProperty));
89
90 // VerifyCmdBuffer could be called for duplicated times for singleTaskPhase mult-pass cases
91 // Each task submit verify only once
92 MEDIA_CHK_STATUS_RETURN(scalability->VerifyCmdBuffer(m_cmdBufSize, m_patchListSize, singleTaskPhaseSupportedInPak));
93 }
94 else
95 {
96 SCALABILITY_ASSERTMESSAGE("No packets to execute in the task!");
97 return MOS_STATUS_INVALID_PARAMETER;
98 }
99
100 int8_t curPipe = -1;
101
102 for (auto& prop : m_packets)
103 {
104 MEDIA_CHK_STATUS_RETURN(scalability->UpdateState(&prop.stateProperty));
105
106 auto packet = prop.packet;
107 uint8_t packetPhase = MediaPacket::otherPacket;
108 MEDIA_CHK_NULL_RETURN(packet);
109
110 MEDIA_CHK_STATUS_RETURN(packet->Prepare());
111
112 MEDIA_CHK_STATUS_RETURN(scalability->GetCmdBuffer(&cmdBuffer, prop.frameTrackingRequested));
113 //Set first packet for each pipe in the first pass, used for prolog & forcewakeup insertion
114 bool isFirstPacket = scalability->GetCurrentPass() == 0 && curPipe < scalability->GetCurrentPipe();
115 if (isFirstPacket)
116 {
117 packetPhase = MediaPacket::firstPacket;
118 }
119
120 if (isFirstPacket || !prop.stateProperty.singleTaskPhaseSupported)
121 {
122 scalability->Oca1stLevelBBStart(cmdBuffer);
123 }
124
125 curPipe = scalability->GetCurrentPipe();
126
127 MEDIA_CHK_STATUS_RETURN(packet->Submit(&cmdBuffer, packetPhase));
128
129 MEDIA_CHK_STATUS_RETURN(scalability->ReturnCmdBuffer(&cmdBuffer));
130 }
131
132 #if (_DEBUG || _RELEASE_INTERNAL) && !EMUL
133 MEDIA_CHK_STATUS_RETURN(DumpCmdBufferAllPipes(&cmdBuffer, debugInterface, scalability));
134 #endif // _DEBUG || _RELEASE_INTERNAL
135
136 // submit cmd buffer
137 MEDIA_CHK_STATUS_RETURN(scalability->SubmitCmdBuffer(&cmdBuffer));
138
139 #if (_DEBUG || _RELEASE_INTERNAL)
140 for (auto prop : m_packets)
141 {
142 MEDIA_CHK_STATUS_RETURN(scalability->UpdateState(&prop.stateProperty));
143
144 auto packet = prop.packet;
145 MEDIA_CHK_NULL_RETURN(packet);
146 MEDIA_CHK_STATUS_RETURN(packet->DumpOutput());
147 }
148 #endif // _DEBUG || _RELEASE_INTERNAL
149
150 // clear the packet lists since all commands are composed into command buffer
151 m_packets.clear();
152
153 return MOS_STATUS_SUCCESS;
154 }
155
156 #if ((_DEBUG || _RELEASE_INTERNAL) && !EMUL)
DumpCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer,CodechalDebugInterface * debugInterface,uint8_t pipeIdx)157 MOS_STATUS CmdTask::DumpCmdBuffer(PMOS_COMMAND_BUFFER cmdBuffer, CodechalDebugInterface *debugInterface, uint8_t pipeIdx)
158 {
159 MEDIA_CHK_NULL_RETURN(cmdBuffer);
160
161 if (debugInterface)
162 {
163 std::string packetName = "";
164 for (auto prop : m_packets)
165 {
166 // Construct cmd buffer dump name only from packets in pipe 0
167 if (prop.stateProperty.currentPipe == 0)
168 {
169 packetName += prop.packet->GetPacketName();
170 break;
171 }
172 }
173
174 // Put pipe index to file name
175 std::stringstream pipeIdxStrStream;
176 pipeIdxStrStream << "_" << uint32_t(pipeIdx);
177 packetName += pipeIdxStrStream.str();
178
179 MEDIA_CHK_STATUS_RETURN(debugInterface->DumpCmdBuffer(
180 cmdBuffer,
181 CODECHAL_NUM_MEDIA_STATES,
182 packetName.data()));
183 }
184
185 return MOS_STATUS_SUCCESS;
186 }
187
DumpCmdBufferAllPipes(PMOS_COMMAND_BUFFER cmdBuffer,CodechalDebugInterface * debugInterface,MediaScalability * scalability)188 MOS_STATUS CmdTask::DumpCmdBufferAllPipes(PMOS_COMMAND_BUFFER cmdBuffer, CodechalDebugInterface *debugInterface, MediaScalability *scalability)
189 {
190 MEDIA_CHK_NULL_RETURN(cmdBuffer);
191 MEDIA_CHK_NULL_RETURN(scalability);
192
193 if (debugInterface)
194 {
195 auto pipeNum = scalability->GetPipeNumber();
196 auto lastPipeIndex = scalability->GetCurrentPipe();
197 for (uint8_t pipeIdx = 0; pipeIdx < pipeNum; pipeIdx++)
198 {
199 scalability->SetCurrentPipeIndex(pipeIdx);
200 MEDIA_CHK_STATUS_RETURN(scalability->GetCmdBuffer(cmdBuffer));
201 MEDIA_CHK_STATUS_RETURN(DumpCmdBuffer(cmdBuffer, debugInterface, pipeIdx));
202 MEDIA_CHK_STATUS_RETURN(scalability->ReturnCmdBuffer(cmdBuffer));
203 }
204
205 // Recover scalability current pipe index after dump
206 scalability->SetCurrentPipeIndex(lastPipeIndex);
207 }
208
209 return MOS_STATUS_SUCCESS;
210 }
211 #endif // _DEBUG || _RELEASE_INTERNAL
212