1 /*
2 * Copyright © 2014 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
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Xiang Haihao <haihao.xiang@intel.com>
26 * Midhunchandra Kodiyath <midhunchandra.kodiyath@intel.com>
27 *
28 */
29
30 #include "media_drv_driver.h"
31 #include "media_drv_batchbuffer.h"
32 #include "media_drv_gpe_utils.h"
33 #include "media_drv_util.h"
34 #include "media_drv_hwcmds.h"
35
36 //#define DEBUG
37 VOID
media_batchbuffer_advance(MEDIA_BATCH_BUFFER * batch)38 media_batchbuffer_advance (MEDIA_BATCH_BUFFER * batch)
39 {
40
41 MEDIA_DRV_ASSERT (batch->emit_total ==
42 (batch->cmd_ptr - batch->emit_start));
43 }
44
45 static VOID
media_batchbuffer_reset(MEDIA_BATCH_BUFFER * batch,INT buffer_size)46 media_batchbuffer_reset (MEDIA_BATCH_BUFFER * batch, INT buffer_size)
47 {
48 struct media_driver_data *drv_data = batch->drv_data;
49 INT batch_size = buffer_size;
50
51 MEDIA_DRV_ASSERT (batch->flag == I915_EXEC_RENDER ||
52 batch->flag == I915_EXEC_BLT ||
53 batch->flag == I915_EXEC_BSD ||
54 batch->flag == I915_EXEC_VEBOX);
55
56 dri_bo_unreference (batch->buffer);
57 batch->buffer = dri_bo_alloc (drv_data->bufmgr,
58 "batch buffer", batch_size, 0x1000);
59 MEDIA_DRV_ASSERT (batch->buffer);
60 dri_bo_map (batch->buffer, 1);
61 MEDIA_DRV_ASSERT (batch->buffer->virtual);
62 batch->map = batch->buffer->virtual;
63 batch->size = batch_size;
64 batch->cmd_ptr = batch->map;
65 batch->atomic = 0;
66 }
67 VOID
media_batchbuffer_submit(MEDIA_BATCH_BUFFER * batch)68 media_batchbuffer_submit (MEDIA_BATCH_BUFFER * batch)
69 {
70 UINT used = batch->cmd_ptr - batch->map;
71 if (used == 0)
72 {
73 return;
74 }
75 if ((used & 4) == 0)
76 {
77 *(UINT *) batch->cmd_ptr = 0;
78 batch->cmd_ptr += 4;
79 }
80
81 *(UINT *) batch->cmd_ptr = MI_BATCH_BUFFER_END;
82 batch->cmd_ptr += 4;
83 dri_bo_unmap (batch->buffer);
84 used = batch->cmd_ptr - batch->map;
85 drm_intel_bo_mrb_exec (batch->buffer, used, 0, 0, 0, batch->flag);
86 media_batchbuffer_free (batch);
87 }
88
89 VOID
media_batchbuffer_flush(MEDIA_BATCH_BUFFER * batch)90 media_batchbuffer_flush (MEDIA_BATCH_BUFFER * batch)
91 {
92 UINT used = batch->cmd_ptr - batch->map;
93 if (used == 0)
94 {
95 return;
96 }
97 if ((used & 4) == 0)
98 {
99 *(UINT *) batch->cmd_ptr = 0;
100 batch->cmd_ptr += 4;
101 }
102
103 *(UINT *) batch->cmd_ptr = MI_BATCH_BUFFER_END;
104 batch->cmd_ptr += 4;
105 dri_bo_unmap (batch->buffer);
106 used = batch->cmd_ptr - batch->map;
107 drm_intel_bo_mrb_exec (batch->buffer, used, 0, 0, 0, batch->flag);
108 media_batchbuffer_reset (batch, batch->size);
109 }
110
111 VOID
media_batchbuffer_begin(MEDIA_BATCH_BUFFER * batch,INT total)112 media_batchbuffer_begin (MEDIA_BATCH_BUFFER * batch, INT total)
113 {
114 batch->emit_total = total * 4;
115 batch->emit_start = batch->cmd_ptr;
116 }
117
118 static UINT
media_batchbuffer_check_space(MEDIA_BATCH_BUFFER * batch)119 media_batchbuffer_check_space (MEDIA_BATCH_BUFFER * batch)
120 {
121 return (batch->size - BATCH_RESERVED) - (batch->cmd_ptr - batch->map);
122 }
123
124 VOID
media_batchbuffer_check_flag(MEDIA_BATCH_BUFFER * batch,INT flag)125 media_batchbuffer_check_flag (MEDIA_BATCH_BUFFER * batch, INT flag)
126 {
127 if (flag != I915_EXEC_RENDER &&
128 flag != I915_EXEC_BLT &&
129 flag != I915_EXEC_BSD && flag != I915_EXEC_VEBOX)
130 return;
131
132 if (batch->flag == flag)
133 return;
134
135 media_batchbuffer_flush (batch);
136 batch->flag = flag;
137 }
138
139 VOID
media_batchbuffer_require_space(MEDIA_BATCH_BUFFER * batch,UINT size)140 media_batchbuffer_require_space (MEDIA_BATCH_BUFFER * batch, UINT size)
141 {
142 MEDIA_DRV_ASSERT (size < batch->size - 8);
143 if (media_batchbuffer_check_space (batch) < size)
144 {
145 media_batchbuffer_flush (batch);
146 }
147 }
148
149 VOID
media_batchbuffer_emit_dword(MEDIA_BATCH_BUFFER * batch,UINT cmd)150 media_batchbuffer_emit_dword (MEDIA_BATCH_BUFFER * batch, UINT cmd)
151 {
152 MEDIA_DRV_ASSERT (media_batchbuffer_check_space (batch) >= 4);
153 *(UINT *) batch->cmd_ptr = cmd;
154 batch->cmd_ptr += 4;
155 }
156
157 VOID
media_batchbuffer_emit_reloc(MEDIA_BATCH_BUFFER * batch,dri_bo * bo,UINT read_domains,UINT write_domains,UINT delta)158 media_batchbuffer_emit_reloc (MEDIA_BATCH_BUFFER * batch, dri_bo * bo,
159 UINT read_domains, UINT write_domains,
160 UINT delta)
161 {
162 assert (batch->cmd_ptr - batch->map < batch->size);
163 dri_bo_emit_reloc (batch->buffer,/* I915_GEM_DOMAIN_RENDER*/ read_domains, write_domains,delta, batch->cmd_ptr - batch->map, bo);
164 media_batchbuffer_emit_dword (batch, bo->offset + delta);
165 }
166
167 MEDIA_BATCH_BUFFER *
media_batchbuffer_new(struct media_driver_data * drv_data,INT flag,INT buffer_size)168 media_batchbuffer_new (struct media_driver_data * drv_data, INT flag,
169 INT buffer_size)
170 {
171 MEDIA_BATCH_BUFFER *batch = media_drv_alloc_memory (sizeof (*batch));
172 MEDIA_DRV_ASSERT (flag == I915_EXEC_RENDER);
173
174 if (!buffer_size || buffer_size < BATCH_SIZE)
175 {
176 buffer_size = BATCH_SIZE;
177 }
178 /* the buffer size can't exceed 4M */
179 if (buffer_size > MAX_BATCH_SIZE)
180 {
181 buffer_size = MAX_BATCH_SIZE;
182 }
183 batch->drv_data = drv_data;
184 batch->flag = flag;
185
186 media_batchbuffer_reset (batch, buffer_size);
187
188 return batch;
189 }
190
191 VOID
media_batchbuffer_free(MEDIA_BATCH_BUFFER * batch)192 media_batchbuffer_free (MEDIA_BATCH_BUFFER * batch)
193 {
194 if (batch->map)
195 {
196 dri_bo_unmap (batch->buffer);
197 batch->map = NULL;
198 }
199
200 dri_bo_unreference (batch->buffer);
201 media_drv_free_memory (batch);
202 }
203
204 BOOL
media_allocate_resource(MEDIA_RESOURCE * res,dri_bufmgr * bufmgr,const BYTE * name,UINT size,UINT align)205 media_allocate_resource (MEDIA_RESOURCE * res, dri_bufmgr * bufmgr,
206 const BYTE * name, UINT size, UINT align)
207 {
208 res->bo = dri_bo_alloc (bufmgr,(const CHAR *) name, size, align);
209 res->bo_size = size;
210 return SUCCESS;
211 }
212
213 BOOL
media_allocate_resource_ext(MEDIA_RESOURCE * res,dri_bufmgr * bufmgr,MEDIA_ALLOC_PARAMS * params,UINT align)214 media_allocate_resource_ext (MEDIA_RESOURCE * res, dri_bufmgr * bufmgr,
215 MEDIA_ALLOC_PARAMS * params, UINT align)
216 {
217 res->bo = dri_bo_alloc (bufmgr,(const CHAR *) params->buf_name, params->bo_size, align);
218 res->bo_size = params->bo_size;
219 res->width = params->width;
220 res->height = params->height;
221 res->tiling = params->tiling;
222
223 return SUCCESS;
224 }
225
226 VOID *
media_map_buffer_obj(dri_bo * bo)227 media_map_buffer_obj (dri_bo * bo)
228 {
229 dri_bo_map (bo, 1);
230 MEDIA_DRV_ASSERT (bo->virtual);
231 return bo->virtual;
232 }
233
234 BOOL
media_unmap_buffer_obj(dri_bo * bo)235 media_unmap_buffer_obj (dri_bo * bo)
236 {
237 dri_bo_unmap (bo);
238 return SUCCESS;
239 }
240
241 void
media_batchbuffer_emit_mi_flush(MEDIA_BATCH_BUFFER * batch)242 media_batchbuffer_emit_mi_flush (MEDIA_BATCH_BUFFER * batch)
243 {
244 struct media_driver_data *drv_data = batch->drv_data;
245
246 if (IS_GEN75(drv_data->device_id) ||
247 IS_CHERRYVIEW(drv_data->device_id) ||
248 IS_GEN8(drv_data->device_id)) {
249 if (batch->flag == I915_EXEC_RENDER) {
250 if (IS_GEN8(drv_data->device_id) ||
251 IS_CHERRYVIEW(drv_data->device_id)) {
252 BEGIN_BATCH(batch, 6);
253 OUT_BATCH(batch, CMD_PIPE_CONTROL | (6 - 2));
254
255 OUT_BATCH(batch,
256 CMD_PIPE_CONTROL_CS_STALL |
257 CMD_PIPE_CONTROL_WC_FLUSH |
258 CMD_PIPE_CONTROL_TC_FLUSH |
259 CMD_PIPE_CONTROL_DC_FLUSH |
260 CMD_PIPE_CONTROL_NOWRITE);
261 OUT_BATCH(batch, 0); /* write address */
262 OUT_BATCH(batch, 0);
263 OUT_BATCH(batch, 0); /* write data */
264 OUT_BATCH(batch, 0);
265 ADVANCE_BATCH(batch);
266 } else {
267 BEGIN_BATCH(batch, 4);
268 OUT_BATCH(batch, CMD_PIPE_CONTROL | (4 - 2));
269
270 OUT_BATCH(batch,
271 CMD_PIPE_CONTROL_WC_FLUSH |
272 CMD_PIPE_CONTROL_TC_FLUSH |
273 CMD_PIPE_CONTROL_DC_FLUSH |
274 CMD_PIPE_CONTROL_NOWRITE);
275 OUT_BATCH(batch, 0); /* write address */
276 OUT_BATCH(batch, 0); /* write data */
277 ADVANCE_BATCH(batch);
278 }
279
280 } else {
281 if (batch->flag == I915_EXEC_BLT) {
282 __BEGIN_BATCH(batch, 4, I915_EXEC_BLT);
283 OUT_BATCH(batch, MI_FLUSH_DW);
284 OUT_BATCH(batch, 0);
285 OUT_BATCH(batch, 0);
286 OUT_BATCH(batch, 0);
287 ADVANCE_BATCH(batch);
288 } else if (batch->flag == I915_EXEC_BSD) {
289 __BEGIN_BATCH(batch, 4, I915_EXEC_BSD);
290 OUT_BATCH(batch, MI_FLUSH_DW | MI_FLUSH_DW_VIDEO_PIPELINE_CACHE_INVALIDATE);
291 OUT_BATCH(batch, 0);
292 OUT_BATCH(batch, 0);
293 OUT_BATCH(batch, 0);
294 ADVANCE_BATCH(batch);
295 }
296 }
297 }
298 }
299
300 static void
media_batchbuffer_start_atomic_helper(MEDIA_BATCH_BUFFER * batch,int flag,unsigned int size)301 media_batchbuffer_start_atomic_helper(MEDIA_BATCH_BUFFER *batch,
302 int flag,
303 unsigned int size)
304 {
305 media_batchbuffer_check_flag(batch, flag);
306 media_batchbuffer_require_space(batch, size);
307 batch->atomic = 1;
308 }
309
310 void
media_batchbuffer_start_atomic(MEDIA_BATCH_BUFFER * batch,unsigned int size)311 media_batchbuffer_start_atomic(MEDIA_BATCH_BUFFER *batch, unsigned int size)
312 {
313 media_batchbuffer_start_atomic_helper(batch, I915_EXEC_RENDER, size);
314 }
315
316 void
media_batchbuffer_start_atomic_blt(MEDIA_BATCH_BUFFER * batch,unsigned int size)317 media_batchbuffer_start_atomic_blt(MEDIA_BATCH_BUFFER *batch, unsigned int size)
318 {
319 media_batchbuffer_start_atomic_helper(batch, I915_EXEC_BLT, size);
320 }
321
322 void
media_batchbuffer_start_atomic_bcs(MEDIA_BATCH_BUFFER * batch,unsigned int size)323 media_batchbuffer_start_atomic_bcs(MEDIA_BATCH_BUFFER *batch, unsigned int size)
324 {
325 media_batchbuffer_start_atomic_helper(batch, I915_EXEC_BSD, size);
326 }
327
328 void
media_batchbuffer_start_atomic_veb(MEDIA_BATCH_BUFFER * batch,unsigned int size)329 media_batchbuffer_start_atomic_veb(MEDIA_BATCH_BUFFER *batch, unsigned int size)
330 {
331 media_batchbuffer_start_atomic_helper(batch, I915_EXEC_VEBOX, size);
332 }
333
334 void
media_batchbuffer_end_atomic(MEDIA_BATCH_BUFFER * batch)335 media_batchbuffer_end_atomic(MEDIA_BATCH_BUFFER *batch)
336 {
337 batch->atomic = 0;
338 }
339