1 /*===================== begin_copyright_notice ==================================
2 
3 * Copyright (c) 2021, Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 
23 ======================= end_copyright_notice ==================================*/
24 
25 //!
26 //! \file     mhw_render_xe_hp_base.cpp
27 //! \brief    Constructs render engine commands on Gen12_5_plus platforms
28 //! \details  Each client facing function both creates a HW command and adds
29 //!           that command to a command or batch buffer.
30 //!
31 
32 #include "mhw_render_xe_hp_base.h"
33 #include "mhw_render_hwcmd_xe_hp_base.h"
34 
AddCfeStateCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VFE_PARAMS params)35 MOS_STATUS MhwRenderInterfaceXe_Xpm_Base::AddCfeStateCmd(
36     PMOS_COMMAND_BUFFER cmdBuffer,
37     PMHW_VFE_PARAMS     params)
38 {
39     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
40 
41     MHW_FUNCTION_ENTER;
42 
43     MHW_MI_CHK_NULL(m_osInterface);
44     MHW_MI_CHK_NULL(cmdBuffer);
45     MHW_MI_CHK_NULL(params);
46 
47     mhw_render_xe_xpm_base::CFE_STATE_CMD cmd;
48 
49     if (params->pKernelState)
50     {
51         MHW_MI_CHK_NULL(params->pKernelState);
52 
53         cmd.DW3.MaximumNumberOfThreads = (params->dwMaximumNumberofThreads) ? params->dwMaximumNumberofThreads - 1 : params->pKernelState->KernelParams.iThreadCount - 1;
54     }
55     else
56     {
57         cmd.DW3.MaximumNumberOfThreads = (params->dwMaximumNumberofThreads) ? params->dwMaximumNumberofThreads - 1 : m_hwCaps.dwMaxThreads - 1;
58     }
59 
60     MHW_VFE_PARAMS_G12 *paramsG12 = dynamic_cast<MHW_VFE_PARAMS_G12 *>(params);
61     if (paramsG12 != nullptr)
62     {
63         cmd.DW1_2.ScratchSpaceBuffer       = paramsG12->scratchStateOffset >> 6;
64         cmd.DW3.FusedEuDispatch            = paramsG12->bFusedEuDispatch ? false : true;  // disabled if DW3.FusedEuDispath = 1
65         cmd.DW3.NumberOfWalkers            = paramsG12->numOfWalkers;
66         cmd.DW3.SingleSliceDispatchCcsMode = paramsG12->enableSingleSliceDispatchCcsMode;
67     }
68     else
69     {
70         MHW_ASSERTMESSAGE("Gen12-Specific CFE Params are needed.");
71         return MOS_STATUS_INVALID_PARAMETER;
72     }
73 
74     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
75 
76     return MOS_STATUS_SUCCESS;
77 }
78 
AddComputeWalkerCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_GPGPU_WALKER_PARAMS gpgpuWalkerParams,PMHW_ID_ENTRY_PARAMS interfaceDescriptorParams,PMOS_RESOURCE postsyncResource,uint32_t resourceOffset)79 MOS_STATUS MhwRenderInterfaceXe_Xpm_Base::AddComputeWalkerCmd(
80     PMOS_COMMAND_BUFFER      cmdBuffer,
81     PMHW_GPGPU_WALKER_PARAMS gpgpuWalkerParams,
82     PMHW_ID_ENTRY_PARAMS     interfaceDescriptorParams,
83     PMOS_RESOURCE            postsyncResource,
84     uint32_t                 resourceOffset)
85 {
86     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
87 
88     MHW_FUNCTION_ENTER;
89 
90     MHW_MI_CHK_NULL(cmdBuffer);
91     MHW_MI_CHK_NULL(gpgpuWalkerParams);
92     MHW_MI_CHK_NULL(interfaceDescriptorParams);
93     MHW_MI_CHK_NULL(m_osInterface);
94     MHW_MI_CHK_NULL(m_osInterface->pfnGetPlatform);
95 
96     if (gpgpuWalkerParams->ThreadDepth == 0)
97     {
98         gpgpuWalkerParams->ThreadDepth = 1;
99     }
100     if (gpgpuWalkerParams->GroupDepth == 0)
101     {
102         gpgpuWalkerParams->GroupDepth = 1;
103     }
104 
105     mhw_render_xe_xpm_base::COMPUTE_WALKER_CMD cmd;
106 
107     cmd.DW2.IndirectDataLength       = gpgpuWalkerParams->IndirectDataLength;
108     cmd.DW3.IndirectDataStartAddress = gpgpuWalkerParams->IndirectDataStartAddress >> MHW_COMPUTE_INDIRECT_SHIFT;
109 
110     cmd.DW4.SIMDSize = mhw_render_xe_xpm_base::COMPUTE_WALKER_CMD::SIMD_SIZE_SIMD32;
111 
112     cmd.DW5.ExecutionMask = 0xffffffff;
113     cmd.DW6.LocalXMaximum = gpgpuWalkerParams->ThreadWidth - 1;
114     cmd.DW6.LocalYMaximum = gpgpuWalkerParams->ThreadHeight - 1;
115     cmd.DW6.LocalZMaximum = gpgpuWalkerParams->ThreadDepth - 1;
116 
117     cmd.DW7.ThreadGroupIDXDimension = gpgpuWalkerParams->GroupWidth - gpgpuWalkerParams->GroupStartingX;
118     cmd.DW8.ThreadGroupIDYDimension = gpgpuWalkerParams->GroupHeight - gpgpuWalkerParams->GroupStartingY;
119     cmd.DW9.ThreadGroupIDZDimension = gpgpuWalkerParams->GroupDepth;
120     cmd.DW10.ThreadGroupIDStartingX = gpgpuWalkerParams->GroupStartingX;
121     cmd.DW11.ThreadGroupIDStartingY = gpgpuWalkerParams->GroupStartingY;
122     cmd.DW12.ThreadGroupIDStartingZ = gpgpuWalkerParams->GroupStartingZ;
123 
124     cmd.interface_descriptor_data.DW0_1.KernelStartPointer              = interfaceDescriptorParams->dwKernelOffset >> MHW_KERNEL_OFFSET_SHIFT;
125     cmd.interface_descriptor_data.DW3.SamplerCount                      = interfaceDescriptorParams->dwSamplerCount;
126     cmd.interface_descriptor_data.DW3.SamplerStatePointer               = interfaceDescriptorParams->dwSamplerOffset >> MHW_SAMPLER_SHIFT;
127     cmd.interface_descriptor_data.DW4.BindingTablePointer               = MOS_ROUNDUP_SHIFT(interfaceDescriptorParams->dwBindingTableOffset, MHW_BINDING_TABLE_ID_SHIFT);
128     cmd.interface_descriptor_data.DW5.BarrierEnable                     = interfaceDescriptorParams->bBarrierEnable;
129     cmd.interface_descriptor_data.DW5.NumberOfThreadsInGpgpuThreadGroup = interfaceDescriptorParams->dwNumberofThreadsInGPGPUGroup;
130     cmd.interface_descriptor_data.DW5.SharedLocalMemorySize             = interfaceDescriptorParams->dwSharedLocalMemorySize;
131 
132     if (nullptr != postsyncResource)
133     {
134         MHW_RESOURCE_PARAMS resourceParams;
135         MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
136         InitMocsParams(resourceParams, &cmd.postsync_data.DW0.Value, 5, 10);
137         resourceParams.presResource    = postsyncResource;
138         resourceParams.pdwCmd          = cmd.postsync_data.DW1_2.Value;
139         resourceParams.dwLocationInCmd = 24;
140         resourceParams.dwOffset        = resourceOffset;
141         resourceParams.bIsWritable     = true;
142         MHW_MI_CHK_STATUS(AddResourceToCmd(m_osInterface,
143             cmdBuffer,
144             &resourceParams));
145         cmd.postsync_data.DW0.Operation = mhw_render_xe_xpm_base::COMPUTE_WALKER_CMD::POSTSYNC_DATA_CMD ::POSTSYNC_OPERATION_WRITE_TIMESTAMP;
146     }
147 
148     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
149     return eStatus;
150 }
151 
AddStateComputeModeCmd(const MHW_STATE_COMPUTE_MODE_PARAMS & computeStateMode,MOS_COMMAND_BUFFER * cmdBuffer)152 MOS_STATUS MhwRenderInterfaceXe_Xpm_Base::AddStateComputeModeCmd(
153     const MHW_STATE_COMPUTE_MODE_PARAMS &computeStateMode,
154     MOS_COMMAND_BUFFER *                 cmdBuffer)
155 {
156     MHW_MI_CHK_NULL(m_osInterface);
157     mhw_render_xe_xpm_base::STATE_COMPUTE_MODE_CMD cmd;
158     cmd.DW1.MaskBits         = 0xFFFF;
159     cmd.DW1.LargeGrfMode     = computeStateMode.enableLargeGrf ? 1 : 0;
160     cmd.DW1.ForceNonCoherent = 2;
161     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
162     return MOS_STATUS_SUCCESS;
163 }
164 
AddStateBaseAddrCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_STATE_BASE_ADDR_PARAMS params)165 MOS_STATUS MhwRenderInterfaceXe_Xpm_Base::AddStateBaseAddrCmd(
166     PMOS_COMMAND_BUFFER         cmdBuffer,
167     PMHW_STATE_BASE_ADDR_PARAMS params)
168 {
169     MHW_FUNCTION_ENTER;
170 
171     MHW_MI_CHK_NULL(m_osInterface);
172     MHW_MI_CHK_NULL(cmdBuffer);
173     MHW_MI_CHK_NULL(params);
174 
175     MHW_RESOURCE_PARAMS resourceParams;
176     MOS_ZeroMemory(&resourceParams, sizeof(resourceParams));
177     resourceParams.dwLsbNum      = MHW_RENDER_ENGINE_STATE_BASE_ADDRESS_SHIFT;
178     resourceParams.HwCommandType = MOS_STATE_BASE_ADDR;
179 
180     mhw_render_xe_xpm_base::STATE_BASE_ADDRESS_CMD cmd;
181 
182     if (params->presGeneralState)
183     {
184         cmd.DW1_2.GeneralStateBaseAddressModifyEnable  = true;
185         cmd.DW12.GeneralStateBufferSizeModifyEnable    = true;
186         resourceParams.presResource                    = params->presGeneralState;
187         resourceParams.dwOffset                        = 0;
188         resourceParams.pdwCmd                          = cmd.DW1_2.Value;
189         resourceParams.dwLocationInCmd                 = 1;
190 
191         // upper bound of the allocated resource will not be set
192         resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;
193 
194         InitMocsParams(resourceParams, &cmd.DW1_2.Value[0], 5, 10);
195 
196         MHW_MI_CHK_STATUS(AddResourceToCmd(
197             m_osInterface,
198             cmdBuffer,
199             &resourceParams));
200 
201         if (params->mocs4GeneralState != 0)
202         {
203             cmd.DW1_2.GeneralStateMemoryObjectControlState = params->mocs4GeneralState;
204         }
205         cmd.DW12.GeneralStateBufferSize = (params->dwGeneralStateSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
206     }
207 
208     if (m_osInterface->bNoParsingAssistanceInKmd)
209     {
210         uint32_t indirectStateOffset, indirectStateSize;
211         MHW_MI_CHK_STATUS(m_osInterface->pfnGetIndirectState(m_osInterface, &indirectStateOffset, &indirectStateSize));
212 
213         // When KMD parsing assistance is not used,
214         // UMD is required to set up the SSH
215         // in the STATE_BASE_ADDRESS command.
216         // All addresses used in the STATE_BASE_ADDRESS
217         // command need to have the modify
218         // bit associated with it set to 1.
219         cmd.DW4_5.SurfaceStateBaseAddressModifyEnable  = true;
220         resourceParams.presResource                    = &cmdBuffer->OsResource;
221         resourceParams.dwOffset                        = indirectStateOffset;
222         resourceParams.pdwCmd                          = cmd.DW4_5.Value;
223         resourceParams.dwLocationInCmd                 = 4;
224 
225         // upper bound of the allocated resource will not be set
226         resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;
227 
228         InitMocsParams(resourceParams, &cmd.DW4_5.Value[0], 5, 10);
229         MHW_MI_CHK_STATUS(AddResourceToCmd(
230             m_osInterface,
231             cmdBuffer,
232             &resourceParams));
233 
234         if (params->mocs4SurfaceState != 0)
235         {
236             cmd.DW4_5.SurfaceStateMemoryObjectControlState = params->mocs4SurfaceState;
237         }
238     }
239 
240     if (params->presDynamicState)
241     {
242         cmd.DW6_7.DynamicStateBaseAddressModifyEnable  = true;
243         cmd.DW13.DynamicStateBufferSizeModifyEnable    = true;
244         resourceParams.presResource                    = params->presDynamicState;
245         resourceParams.dwOffset                        = 0;
246         resourceParams.pdwCmd                          = cmd.DW6_7.Value;
247         resourceParams.dwLocationInCmd                 = 6;
248         resourceParams.bIsWritable                     = params->bDynamicStateRenderTarget;
249 
250         // upper bound of the allocated resource will not be set
251         resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;
252 
253         InitMocsParams(resourceParams, &cmd.DW6_7.Value[0], 5, 10);
254         MHW_MI_CHK_STATUS(AddResourceToCmd(
255             m_osInterface,
256             cmdBuffer,
257             &resourceParams));
258 
259         if (params->mocs4DynamicState != 0)
260         {
261             cmd.DW6_7.DynamicStateMemoryObjectControlState = params->mocs4DynamicState;
262         }
263 
264         cmd.DW13.DynamicStateBufferSize = (params->dwDynamicStateSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
265 
266         //Reset bRenderTarget as it should be enabled only for Dynamic State
267         resourceParams.bIsWritable = false;
268     }
269 
270     if (params->presIndirectObjectBuffer)
271     {
272         cmd.DW8_9.IndirectObjectBaseAddressModifyEnable  = true;
273         cmd.DW14.IndirectObjectBufferSizeModifyEnable    = true;
274         resourceParams.presResource                      = params->presIndirectObjectBuffer;
275         resourceParams.dwOffset                          = 0;
276         resourceParams.pdwCmd                            = cmd.DW8_9.Value;
277         resourceParams.dwLocationInCmd                   = 8;
278 
279         // upper bound of the allocated resource will not be set
280         resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;
281 
282         InitMocsParams(resourceParams, &cmd.DW8_9.Value[0], 5, 10);
283         MHW_MI_CHK_STATUS(AddResourceToCmd(
284             m_osInterface,
285             cmdBuffer,
286             &resourceParams));
287 
288         if (params->mocs4IndirectObjectBuffer != 0)
289         {
290             cmd.DW8_9.IndirectObjectMemoryObjectControlState = params->mocs4IndirectObjectBuffer;
291         }
292         cmd.DW14.IndirectObjectBufferSize = (params->dwIndirectObjectBufferSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
293     }
294 
295     if (params->presInstructionBuffer)
296     {
297         cmd.DW10_11.InstructionBaseAddressModifyEnable  = true;
298         cmd.DW15.InstructionBufferSizeModifyEnable      = true;
299         resourceParams.presResource                     = params->presInstructionBuffer;
300         resourceParams.dwOffset                         = 0;
301         resourceParams.pdwCmd                           = cmd.DW10_11.Value;
302         resourceParams.dwLocationInCmd                  = 10;
303 
304         // upper bound of the allocated resource will not be set
305         resourceParams.dwUpperBoundLocationOffsetFromCmd = 0;
306 
307         InitMocsParams(resourceParams, &cmd.DW10_11.Value[0], 5, 10);
308 
309         MHW_MI_CHK_STATUS(AddResourceToCmd(
310             m_osInterface,
311             cmdBuffer,
312             &resourceParams));
313 
314         if (params->mocs4InstructionCache != 0)
315         {
316             cmd.DW10_11.InstructionMemoryObjectControlState = params->mocs4InstructionCache;
317         }
318         cmd.DW15.InstructionBufferSize = (params->dwInstructionBufferSize + MHW_PAGE_SIZE - 1) / MHW_PAGE_SIZE;
319     }
320 
321     // stateless dataport access
322     cmd.DW3.StatelessDataPortAccessMemoryObjectControlState = params->mocs4StatelessDataport;
323     cmd.DW3.L1CachePolicy                                   = params->l1CacheConfig;
324 
325     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
326 
327     return MOS_STATUS_SUCCESS;
328 }
329 
Add3DStateBindingTablePoolAllocCmd(MOS_COMMAND_BUFFER * cmdBuffer,mhw_render_xe_xpm_base::_3DSTATE_BINDING_TABLE_POOL_ALLOC_CMD cmd)330 MOS_STATUS MhwRenderInterfaceXe_Xpm_Base::Add3DStateBindingTablePoolAllocCmd(
331     MOS_COMMAND_BUFFER *                                       cmdBuffer,
332     mhw_render_xe_xpm_base::_3DSTATE_BINDING_TABLE_POOL_ALLOC_CMD cmd)
333 {
334     uint32_t indirect_state_offset = 0, indirect_state_size = 0;
335     MHW_MI_CHK_NULL(m_osInterface);
336     MHW_MI_CHK_STATUS(m_osInterface->pfnGetIndirectState(m_osInterface,
337         &indirect_state_offset,
338         &indirect_state_size));
339 
340     MHW_RESOURCE_PARAMS resource_params;
341     MOS_ZeroMemory(&resource_params, sizeof(resource_params));
342 
343     InitMocsParams(resource_params, &cmd.DW1_2.Value[0], 1, 6);
344     resource_params.dwLsbNum        = MHW_RENDER_ENGINE_STATE_BASE_ADDRESS_SHIFT;
345     resource_params.HwCommandType   = MOS_STATE_BASE_ADDR;
346     resource_params.presResource    = &cmdBuffer->OsResource;
347     resource_params.dwOffset        = indirect_state_offset;
348     resource_params.pdwCmd          = cmd.DW1_2.Value;
349     resource_params.dwLocationInCmd = 1;
350     MHW_MI_CHK_STATUS(AddResourceToCmd(
351         m_osInterface,
352         cmdBuffer,
353         &resource_params));
354 
355     cmd.DW3.BindingTablePoolBufferSize = indirect_state_size;
356     MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, cmd.byteSize));
357     return MOS_STATUS_SUCCESS;
358 }
359