1 /*
2  * Copyright © 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 (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * 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 OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24 
25 #include <intel_bufmgr.h>
26 #include <i915_drm.h>
27 
28 #include "media_fill.h"
29 #include "gen7_media.h"
30 #include "gen8_media.h"
31 #include "intel_reg.h"
32 #include "drmtest.h"
33 #include "gpu_cmds.h"
34 #include <assert.h>
35 
36 static const uint32_t gen7_media_kernel[][4] = {
37 	{ 0x00400001, 0x20200231, 0x00000020, 0x00000000 },
38 	{ 0x00600001, 0x20800021, 0x008d0000, 0x00000000 },
39 	{ 0x00200001, 0x20800021, 0x00450040, 0x00000000 },
40 	{ 0x00000001, 0x20880061, 0x00000000, 0x000f000f },
41 	{ 0x00800001, 0x20a00021, 0x00000020, 0x00000000 },
42 	{ 0x00800001, 0x20e00021, 0x00000020, 0x00000000 },
43 	{ 0x00800001, 0x21200021, 0x00000020, 0x00000000 },
44 	{ 0x00800001, 0x21600021, 0x00000020, 0x00000000 },
45 	{ 0x05800031, 0x24001ca8, 0x00000080, 0x120a8000 },
46 	{ 0x00600001, 0x2e000021, 0x008d0000, 0x00000000 },
47 	{ 0x07800031, 0x20001ca8, 0x00000e00, 0x82000010 },
48 };
49 
50 static const uint32_t gen8_media_kernel[][4] = {
51 	{ 0x00400001, 0x20202288, 0x00000020, 0x00000000 },
52 	{ 0x00600001, 0x20800208, 0x008d0000, 0x00000000 },
53 	{ 0x00200001, 0x20800208, 0x00450040, 0x00000000 },
54 	{ 0x00000001, 0x20880608, 0x00000000, 0x000f000f },
55 	{ 0x00800001, 0x20a00208, 0x00000020, 0x00000000 },
56 	{ 0x00800001, 0x20e00208, 0x00000020, 0x00000000 },
57 	{ 0x00800001, 0x21200208, 0x00000020, 0x00000000 },
58 	{ 0x00800001, 0x21600208, 0x00000020, 0x00000000 },
59 	{ 0x0c800031, 0x24000a40, 0x0e000080, 0x120a8000 },
60 	{ 0x00600001, 0x2e000208, 0x008d0000, 0x00000000 },
61 	{ 0x07800031, 0x20000a40, 0x0e000e00, 0x82000010 },
62 };
63 
64 static const uint32_t gen11_media_vme_kernel[][4] = {
65 	{ 0x00600001, 0x20302e68,  0x00000000,  0x20000000 },
66 	{ 0x00600001, 0x22802e68,  0x00000000,  0x00000001 },
67 	{ 0x00000001, 0x20284f2c,  0x00000000,  0x3818000c },
68 	{ 0x00600001, 0x22902e68,  0x00000000,  0x00000010 },
69 	{ 0x00600001, 0x22a02e68,  0x00000000,  0x00010000 },
70 	{ 0x00000001, 0x202c4f2c,  0x00000000,  0x22222222 },
71 	{ 0x00000040, 0x22000a20,  0x0e000020,  0x10782000 },
72 	{ 0x00600001, 0x20404f28,  0x00000000,  0x00000000 },
73 	{ 0x00600001, 0x20a04f28,  0x00000000,  0x00000000 },
74 	{ 0x00600001, 0x20c04f28,  0x00000000,  0x00000000 },
75 	{ 0x00600001, 0x21204f28,  0x00000000,  0x00000000 },
76 	{ 0x00600001, 0x20601a28,  0x008d0030,  0x00000000 },
77 	{ 0x00600041, 0x20800a28,  0x1a000028,  0x008d0280 },
78 	{ 0x00600041, 0x20e01a28,  0x1e8d0290,  0x01000100 },
79 	{ 0x00600041, 0x21000a28,  0x1a00002c,  0x008d02a0 },
80 	{ 0x00000001, 0x22284f2c,  0x00000000,  0x00000000 },
81 	{ 0x0d80c031, 0x21404a48,  0x00000040,  0x00000200 },
82 	{ 0x00000001, 0x215c4708,  0x00000000,  0xbeefbeef },
83 	{ 0x00000040, 0x22000204,  0x06000024,  0x020a0400 },
84 	{ 0x00000001, 0x215e4708,  0x00000000,  0xdeaddead },
85 	{ 0x00000001, 0x22484f2c,  0x00000000,  0x00000008 },
86 	{ 0x00000001, 0x22684f2c,  0x00000000,  0x0000000c },
87 	{ 0x00600001, 0x2fe04b2c,  0x008d0000,  0x00000000 },
88 	{ 0x0a800033, 0x0000a054,  0x00002224,  0x00000000 },
89 	{ 0x00000040, 0x22000204,  0x06000024,  0x020a0300 },
90 	{ 0x0a800033, 0x0000e054,  0x00002242,  0x00000000 },
91 	{ 0x00000040, 0x22000204,  0x06000024,  0x020a0200 },
92 	{ 0x0a600033, 0x00010014,  0x00002261,  0x00000000 },
93 	{ 0x07600031, 0x20004a04,  0x06000fe0,  0x82000010 },
94 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
95 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
96 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
97 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
98 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
99 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
100 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
101 	{ 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
102 };
103 
104 /*
105  * This sets up the media pipeline,
106  *
107  * +---------------+ <---- 4096
108  * |       ^       |
109  * |       |       |
110  * |    various    |
111  * |      state    |
112  * |       |       |
113  * |_______|_______| <---- 2048 + ?
114  * |       ^       |
115  * |       |       |
116  * |   batch       |
117  * |    commands   |
118  * |       |       |
119  * |       |       |
120  * +---------------+ <---- 0 + ?
121  *
122  */
123 
124 #define BATCH_STATE_SPLIT 2048
125 /* VFE STATE params */
126 #define THREADS 1
127 #define MEDIA_URB_ENTRIES 2
128 #define MEDIA_URB_SIZE 2
129 #define MEDIA_CURBE_SIZE 2
130 #define GEN7_VFE_STATE_MEDIA_MODE 0
131 
132 void
gen7_media_fillfunc(struct intel_batchbuffer * batch,const struct igt_buf * dst,unsigned int x,unsigned int y,unsigned int width,unsigned int height,uint8_t color)133 gen7_media_fillfunc(struct intel_batchbuffer *batch,
134 		    const struct igt_buf *dst,
135 		    unsigned int x, unsigned int y,
136 		    unsigned int width, unsigned int height,
137 		    uint8_t color)
138 {
139 	uint32_t curbe_buffer, interface_descriptor;
140 	uint32_t batch_end;
141 
142 	intel_batchbuffer_flush(batch);
143 
144 	/* setup states */
145 	batch->ptr = &batch->buffer[BATCH_STATE_SPLIT];
146 
147 	curbe_buffer = gen7_fill_curbe_buffer_data(batch, color);
148 	interface_descriptor = gen7_fill_interface_descriptor(batch, dst,
149 					gen7_media_kernel,
150 					sizeof(gen7_media_kernel));
151 	igt_assert(batch->ptr < &batch->buffer[4095]);
152 
153 	/* media pipeline */
154 	batch->ptr = batch->buffer;
155 	OUT_BATCH(GEN7_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
156 	gen7_emit_state_base_address(batch);
157 
158 	gen7_emit_vfe_state(batch, THREADS, MEDIA_URB_ENTRIES, MEDIA_URB_SIZE,
159 			    MEDIA_CURBE_SIZE, GEN7_VFE_STATE_MEDIA_MODE);;
160 
161 	gen7_emit_curbe_load(batch, curbe_buffer);
162 
163 	gen7_emit_interface_descriptor_load(batch, interface_descriptor);
164 
165 	gen7_emit_media_objects(batch, x, y, width, height);
166 
167 	OUT_BATCH(MI_BATCH_BUFFER_END);
168 
169 	batch_end = intel_batchbuffer_align(batch, 8);
170 	igt_assert(batch_end < BATCH_STATE_SPLIT);
171 
172 	gen7_render_flush(batch, batch_end);
173 	intel_batchbuffer_reset(batch);
174 }
175 
176 void
gen8_media_fillfunc(struct intel_batchbuffer * batch,const struct igt_buf * dst,unsigned int x,unsigned int y,unsigned int width,unsigned int height,uint8_t color)177 gen8_media_fillfunc(struct intel_batchbuffer *batch,
178 		    const struct igt_buf *dst,
179 		    unsigned int x, unsigned int y,
180 		    unsigned int width, unsigned int height,
181 		    uint8_t color)
182 {
183 	uint32_t curbe_buffer, interface_descriptor;
184 	uint32_t batch_end;
185 
186 	intel_batchbuffer_flush(batch);
187 
188 	/* setup states */
189 	batch->ptr = &batch->buffer[BATCH_STATE_SPLIT];
190 
191 	curbe_buffer = gen7_fill_curbe_buffer_data(batch, color);
192 	interface_descriptor = gen8_fill_interface_descriptor(batch, dst,
193 					gen8_media_kernel,
194 					sizeof(gen8_media_kernel));
195 	igt_assert(batch->ptr < &batch->buffer[4095]);
196 
197 	/* media pipeline */
198 	batch->ptr = batch->buffer;
199 	OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
200 	gen8_emit_state_base_address(batch);
201 
202 	gen8_emit_vfe_state(batch, THREADS, MEDIA_URB_ENTRIES, MEDIA_URB_SIZE,
203 			    MEDIA_CURBE_SIZE);
204 
205 	gen7_emit_curbe_load(batch, curbe_buffer);
206 
207 	gen7_emit_interface_descriptor_load(batch, interface_descriptor);
208 
209 	gen7_emit_media_objects(batch, x, y, width, height);
210 
211 	OUT_BATCH(MI_BATCH_BUFFER_END);
212 
213 	batch_end = intel_batchbuffer_align(batch, 8);
214 	igt_assert(batch_end < BATCH_STATE_SPLIT);
215 
216 	gen7_render_flush(batch, batch_end);
217 	intel_batchbuffer_reset(batch);
218 }
219 
220 static void
__gen9_media_fillfunc(struct intel_batchbuffer * batch,const struct igt_buf * dst,unsigned int x,unsigned int y,unsigned int width,unsigned int height,uint8_t color,const uint32_t kernel[][4],size_t kernel_size)221 __gen9_media_fillfunc(struct intel_batchbuffer *batch,
222 		      const struct igt_buf *dst,
223 		      unsigned int x, unsigned int y,
224 		      unsigned int width, unsigned int height,
225 		      uint8_t color, const uint32_t kernel[][4],
226 		      size_t kernel_size)
227 {
228 	uint32_t curbe_buffer, interface_descriptor;
229 	uint32_t batch_end;
230 
231 	intel_batchbuffer_flush(batch);
232 
233 	/* setup states */
234 	batch->ptr = &batch->buffer[BATCH_STATE_SPLIT];
235 
236 	curbe_buffer = gen7_fill_curbe_buffer_data(batch, color);
237 	interface_descriptor = gen8_fill_interface_descriptor(batch, dst,
238 					kernel, kernel_size);
239 	assert(batch->ptr < &batch->buffer[4095]);
240 
241 	/* media pipeline */
242 	batch->ptr = batch->buffer;
243 	OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
244 		  GEN9_FORCE_MEDIA_AWAKE_ENABLE |
245 		  GEN9_SAMPLER_DOP_GATE_DISABLE |
246 		  GEN9_PIPELINE_SELECTION_MASK |
247 		  GEN9_SAMPLER_DOP_GATE_MASK |
248 		  GEN9_FORCE_MEDIA_AWAKE_MASK);
249 	gen9_emit_state_base_address(batch);
250 
251 	gen8_emit_vfe_state(batch, THREADS, MEDIA_URB_ENTRIES, MEDIA_URB_SIZE,
252 			    MEDIA_CURBE_SIZE);
253 
254 	gen7_emit_curbe_load(batch, curbe_buffer);
255 
256 	gen7_emit_interface_descriptor_load(batch, interface_descriptor);
257 
258 	gen7_emit_media_objects(batch, x, y, width, height);
259 
260 	OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
261 		  GEN9_FORCE_MEDIA_AWAKE_DISABLE |
262 		  GEN9_SAMPLER_DOP_GATE_ENABLE |
263 		  GEN9_PIPELINE_SELECTION_MASK |
264 		  GEN9_SAMPLER_DOP_GATE_MASK |
265 		  GEN9_FORCE_MEDIA_AWAKE_MASK);
266 
267 	OUT_BATCH(MI_BATCH_BUFFER_END);
268 
269 	batch_end = intel_batchbuffer_align(batch, 8);
270 	assert(batch_end < BATCH_STATE_SPLIT);
271 
272 	gen7_render_flush(batch, batch_end);
273 	intel_batchbuffer_reset(batch);
274 }
275 
276 void
gen9_media_fillfunc(struct intel_batchbuffer * batch,const struct igt_buf * dst,unsigned int x,unsigned int y,unsigned int width,unsigned int height,uint8_t color)277 gen9_media_fillfunc(struct intel_batchbuffer *batch,
278 		    const struct igt_buf *dst,
279 		    unsigned int x, unsigned int y,
280 		    unsigned int width, unsigned int height,
281 		    uint8_t color)
282 {
283 
284 	__gen9_media_fillfunc(batch, dst, x, y, width, height, color,
285 			      gen8_media_kernel, sizeof(gen8_media_kernel));
286 
287 }
288 
289 static void
__gen11_media_vme_func(struct intel_batchbuffer * batch,const struct igt_buf * src,unsigned int width,unsigned int height,const struct igt_buf * dst,const uint32_t kernel[][4],size_t kernel_size)290 __gen11_media_vme_func(struct intel_batchbuffer *batch,
291 		       const struct igt_buf *src,
292 		       unsigned int width, unsigned int height,
293 		       const struct igt_buf *dst,
294 		       const uint32_t kernel[][4],
295 		       size_t kernel_size)
296 {
297 	uint32_t curbe_buffer, interface_descriptor;
298 	uint32_t batch_end;
299 
300 	intel_batchbuffer_flush(batch);
301 
302 	/* setup states */
303 	batch->ptr = &batch->buffer[BATCH_STATE_SPLIT];
304 
305 	curbe_buffer = gen11_fill_curbe_buffer_data(batch);
306 	interface_descriptor = gen11_fill_interface_descriptor(batch, src, dst,
307 					kernel, kernel_size);
308 	assert(batch->ptr < &batch->buffer[4095]);
309 
310 	/* media pipeline */
311 	batch->ptr = batch->buffer;
312 	OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
313 		  GEN9_FORCE_MEDIA_AWAKE_ENABLE |
314 		  GEN9_SAMPLER_DOP_GATE_DISABLE |
315 		  GEN9_PIPELINE_SELECTION_MASK |
316 		  GEN9_SAMPLER_DOP_GATE_MASK |
317 		  GEN9_FORCE_MEDIA_AWAKE_MASK);
318 	gen9_emit_state_base_address(batch);
319 
320 	gen8_emit_vfe_state(batch, THREADS, MEDIA_URB_ENTRIES, MEDIA_URB_SIZE,
321 			    MEDIA_CURBE_SIZE);
322 
323 	gen7_emit_curbe_load(batch, curbe_buffer);
324 
325 	gen7_emit_interface_descriptor_load(batch, interface_descriptor);
326 
327 	gen7_emit_media_objects(batch, 0, 0, width, height);
328 
329 	OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
330 		  GEN9_FORCE_MEDIA_AWAKE_DISABLE |
331 		  GEN9_SAMPLER_DOP_GATE_ENABLE |
332 		  GEN9_PIPELINE_SELECTION_MASK |
333 		  GEN9_SAMPLER_DOP_GATE_MASK |
334 		  GEN9_FORCE_MEDIA_AWAKE_MASK);
335 
336 	OUT_BATCH(MI_BATCH_BUFFER_END);
337 
338 	batch_end = intel_batchbuffer_align(batch, 8);
339 	assert(batch_end < BATCH_STATE_SPLIT);
340 
341 	gen7_render_context_flush(batch, batch_end);
342 	intel_batchbuffer_reset(batch);
343 }
344 
345 void
gen11_media_vme_func(struct intel_batchbuffer * batch,const struct igt_buf * src,unsigned int width,unsigned int height,const struct igt_buf * dst)346 gen11_media_vme_func(struct intel_batchbuffer *batch,
347 		     const struct igt_buf *src,
348 		     unsigned int width, unsigned int height,
349 		     const struct igt_buf *dst)
350 {
351 	__gen11_media_vme_func(batch,
352 			       src,
353 			       width, height,
354 			       dst,
355 			       gen11_media_vme_kernel,
356 			       sizeof(gen11_media_vme_kernel));
357 }
358