1 /*
2 * Copyright (c) 2018-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 cm_command_buffer_os.cpp
24 //! \brief Contains Class CmCommandBuffer definitions
25 //!
26
27 #include "cm_command_buffer.h"
28 #include "cm_ish.h"
29 #include "cm_ssh.h"
30 #include "cm_media_state.h"
31 #include "cm_thread_space_rt.h"
32 #include "cm_mem.h"
33 #include "cm_kernel_ex.h"
34 #include "cm_group_space.h"
35 #if IGFX_GEN12_SUPPORTED
36 #include "mhw_render_g12_X.h"
37 #include "mhw_mi_g12_X.h"
38 #include "cm_hal_g12.h"
39 #endif
40 #include "mos_solo_generic.h"
41 #include "mhw_mmio_g9.h"
42
AddFrameTracker(MOS_RESOURCE * resource,uint32_t offset,uint32_t tag)43 MOS_STATUS CmCommandBuffer::AddFrameTracker(MOS_RESOURCE *resource, uint32_t offset, uint32_t tag)
44 {
45 MHW_MI_STORE_DATA_PARAMS storeDataParams;
46 MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
47 storeDataParams.pOsResource = resource;
48 storeDataParams.dwResourceOffset = offset;
49 storeDataParams.dwValue = tag;
50 return m_miInterface->AddMiStoreDataImmCmd(&m_cmdBuf, &storeDataParams);
51 }
52
AddConditionalFrameTracker(MOS_RESOURCE * resource,uint32_t offset,uint32_t tag,CM_HAL_CONDITIONAL_BB_END_INFO * cbbInfo)53 MOS_STATUS CmCommandBuffer::AddConditionalFrameTracker(MOS_RESOURCE *resource, uint32_t offset, uint32_t tag, CM_HAL_CONDITIONAL_BB_END_INFO *cbbInfo)
54 {
55 MHW_MI_LOAD_REGISTER_REG_PARAMS loadRegRegParams;
56 MHW_MI_LOAD_REGISTER_IMM_PARAMS loadRegImmParams;
57 MHW_MI_LOAD_REGISTER_MEM_PARAMS loadRegMemParams;
58
59 MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
60 MHW_MI_STORE_DATA_PARAMS storeDataParams;
61 MHW_MI_MATH_PARAMS mathParams;
62 MHW_MI_ALU_PARAMS aluParams[20];
63 MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegMemParams;
64 MHW_PIPE_CONTROL_PARAMS pipeCtrlParams;
65
66 MOS_ZeroMemory(&mathParams, sizeof(mathParams));
67 MOS_ZeroMemory(&aluParams, sizeof(aluParams));
68
69 int aluCount = 0;
70
71 aluParams[aluCount].AluOpcode = MHW_MI_ALU_AND;
72 ++ aluCount;
73
74 // store reg1, CF
75 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
76 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG1;
77 aluParams[aluCount].Operand2 = MHW_MI_ALU_CF;
78 ++ aluCount;
79 // store reg2, CF
80 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
81 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG2;
82 aluParams[aluCount].Operand2 = MHW_MI_ALU_CF;
83 ++ aluCount;
84 // store reg3, CF
85 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
86 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG3;
87 aluParams[aluCount].Operand2 = MHW_MI_ALU_CF;
88 ++ aluCount;
89
90 mathParams.pAluPayload = aluParams;
91 mathParams.dwNumAluParams = aluCount;
92 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiMathCmd(&m_cmdBuf, &mathParams));
93
94 // miload reg1, *(cbb_buffer + offset)
95 MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
96 loadRegMemParams.presStoreBuffer = &(m_cmhal->bufferTable[cbbInfo->bufferTableIndex].osResource);
97 loadRegMemParams.dwOffset = cbbInfo->offset;
98 loadRegMemParams.dwRegister = CS_GPR_REGISTER_INDEX(1);
99 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(&m_cmdBuf, &loadRegMemParams));
100
101 // miload reg8, *(tracker_resource + tracker_offset)
102 MOS_ZeroMemory(&loadRegMemParams, sizeof(loadRegMemParams));
103 loadRegMemParams.presStoreBuffer = resource;
104 loadRegMemParams.dwOffset = offset;
105 loadRegMemParams.dwRegister = CS_GPR_REGISTER_INDEX(8);
106 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(&m_cmdBuf, &loadRegMemParams));
107
108 // miload reg9, tag
109 MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
110 loadRegImmParams.dwData = tag;
111 loadRegImmParams.dwRegister = CS_GPR_REGISTER_INDEX(9);
112 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(&m_cmdBuf, &loadRegImmParams));
113
114 if (!cbbInfo->disableCompareMask)
115 {
116 // miload reg2, mask
117 loadRegMemParams.presStoreBuffer = &(m_cmhal->bufferTable[cbbInfo->bufferTableIndex].osResource);
118 loadRegMemParams.dwOffset = cbbInfo->offset + 4; // in mask mode, the mask stored in the next DW to the value
119 loadRegMemParams.dwRegister = CS_GPR_REGISTER_INDEX(2);
120
121 aluCount = 0;
122
123 //load1 srca, reg1
124 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
125 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
126 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG1;
127 ++ aluCount;
128 //load srcb, reg2
129 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
130 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
131 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG2;
132 ++ aluCount;
133 //add
134 aluParams[aluCount].AluOpcode = MHW_MI_ALU_AND;
135 ++ aluCount;
136 //store reg1, accu
137 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
138 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG1;
139 aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
140 ++ aluCount;
141
142 mathParams.pAluPayload = aluParams;
143 mathParams.dwNumAluParams = aluCount;;
144 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiMathCmd(&m_cmdBuf, &mathParams));
145 }
146
147 // miload reg2, cbb->value
148 MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
149 loadRegImmParams.dwData = cbbInfo->compareValue;
150 loadRegImmParams.dwRegister = CS_GPR_REGISTER_INDEX(2);
151 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(&m_cmdBuf, &loadRegImmParams)); //R2: user value 32bits
152
153 // miload reg3, 1
154 MOS_ZeroMemory(&loadRegImmParams, sizeof(loadRegImmParams));
155 loadRegImmParams.dwData = 1;
156 loadRegImmParams.dwRegister = CS_GPR_REGISTER_INDEX(3);
157 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(&m_cmdBuf, &loadRegImmParams)); //R3 = 1
158
159 aluCount = 0;
160
161 // load srcB, reg1
162 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
163 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
164 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG1;
165 ++ aluCount;
166 // load srcA, reg2
167 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
168 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
169 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG2;
170 ++ aluCount;
171 // sub srcA, srcB
172 aluParams[aluCount].AluOpcode = MHW_MI_ALU_SUB;
173 ++ aluCount;
174 // storeinv reg4, CF --- if (compared > cbb->value) reg4 = -1; else reg4 = -2
175 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STOREINV;
176 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG4;
177 aluParams[aluCount].Operand2 = MHW_MI_ALU_CF;
178 ++ aluCount;
179 mathParams.pAluPayload = aluParams;
180 mathParams.dwNumAluParams = aluCount;
181 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiMathCmd(&m_cmdBuf, &mathParams));
182
183 aluCount = 0;
184
185 // load srcA, reg3
186 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
187 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
188 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG3;
189 ++ aluCount;
190 // load srcB, reg4
191 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
192 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
193 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG4;
194 ++ aluCount;
195 // add
196 aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
197 ++ aluCount;
198 // store reg10, accu --- if (compared > cbb->value) reg10 = 0; else reg10 = -1
199 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
200 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG10;
201 aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
202 ++ aluCount;
203 // load srcA, reg8
204 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
205 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
206 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG8;
207 ++ aluCount;
208 // load srcB, reg10
209 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
210 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
211 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG10;
212 ++ aluCount;
213 // and
214 aluParams[aluCount].AluOpcode = MHW_MI_ALU_AND;
215 ++ aluCount;
216 // store reg11, accu --- if (compared > cbb->value) reg11 = 0; else reg11 = cur_tracker
217 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
218 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG11;
219 aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
220 ++ aluCount;
221 // storeinv reg12, reg10 --- if (compared > cbb->value) reg12 = -1; else reg12 = 0
222 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STOREINV;
223 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG12;
224 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG10;
225 ++ aluCount;
226 // load srcA, reg9
227 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
228 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
229 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG9;
230 ++ aluCount;
231 // load srcB, reg12
232 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
233 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
234 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG12;
235 ++ aluCount;
236 // and
237 aluParams[aluCount].AluOpcode = MHW_MI_ALU_AND;
238 ++ aluCount;
239 // store reg13, accu --- if (compared > cbb->value) reg13 = tracker; else reg13 = 0
240 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
241 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG13;
242 aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
243 ++ aluCount;
244 // load srcA, reg11
245 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
246 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
247 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG11;
248 ++ aluCount;
249 // load srcB, reg13
250 aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
251 aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
252 aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG13;
253 ++ aluCount;
254 // add
255 aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
256 ++ aluCount;
257 // store reg15, accu --- if (compared > cbb->value) reg15 = tracker; else reg15 = cur_tracker
258 aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
259 aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG15;
260 aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
261 ++ aluCount;
262
263 mathParams.pAluPayload = aluParams;
264 mathParams.dwNumAluParams = aluCount;
265 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiMathCmd(&m_cmdBuf, &mathParams));
266
267 // Store reg13 to trackerResource
268 MOS_ZeroMemory(&storeRegMemParams, sizeof(storeRegMemParams));
269 storeRegMemParams.presStoreBuffer = resource;
270 storeRegMemParams.dwOffset = offset;
271 storeRegMemParams.dwRegister = CS_GPR_REGISTER_INDEX(15);
272 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&m_cmdBuf, &storeRegMemParams));
273
274 // Insert a pipe control for synchronization
275 MOS_ZeroMemory(&pipeCtrlParams, sizeof(pipeCtrlParams));
276 pipeCtrlParams.bFlushRenderTargetCache = true;
277 pipeCtrlParams.dwPostSyncOp = MHW_FLUSH_NOWRITE;
278 pipeCtrlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
279 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddPipeControl(&m_cmdBuf, nullptr, &pipeCtrlParams));
280
281 pipeCtrlParams.dwFlushMode = MHW_FLUSH_READ_CACHE;
282 CM_CHK_MOSSTATUS_RETURN(m_miInterface->AddPipeControl(&m_cmdBuf, nullptr, &pipeCtrlParams));
283
284 return MOS_STATUS_SUCCESS;
285 }
286