1 #include <assert.h>
2 #include <stdlib.h>
3 #include <sys/ioctl.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <fcntl.h>
8 #include <inttypes.h>
9 #include <errno.h>
10 #include <sys/stat.h>
11 #include <sys/time.h>
12 #include "drm.h"
13 #include "i915_drm.h"
14 #include "drmtest.h"
15 #include "intel_bufmgr.h"
16 #include "intel_batchbuffer.h"
17 #include "intel_io.h"
18 #include "rendercopy.h"
19 #include "gen6_render.h"
20 #include "intel_reg.h"
21 
22 #define VERTEX_SIZE (3*4)
23 
24 static const uint32_t ps_kernel_nomask_affine[][4] = {
25 	{ 0x0060005a, 0x204077be, 0x000000c0, 0x008d0040 },
26 	{ 0x0060005a, 0x206077be, 0x000000c0, 0x008d0080 },
27 	{ 0x0060005a, 0x208077be, 0x000000d0, 0x008d0040 },
28 	{ 0x0060005a, 0x20a077be, 0x000000d0, 0x008d0080 },
29 	{ 0x00000201, 0x20080061, 0x00000000, 0x00000000 },
30 	{ 0x00600001, 0x20200022, 0x008d0000, 0x00000000 },
31 	{ 0x02800031, 0x21c01cc9, 0x00000020, 0x0a8a0001 },
32 	{ 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 },
33 	{ 0x00600001, 0x206003be, 0x008d01e0, 0x00000000 },
34 	{ 0x00600001, 0x208003be, 0x008d0200, 0x00000000 },
35 	{ 0x00600001, 0x20a003be, 0x008d0220, 0x00000000 },
36 	{ 0x00600001, 0x20c003be, 0x008d0240, 0x00000000 },
37 	{ 0x00600001, 0x20e003be, 0x008d0260, 0x00000000 },
38 	{ 0x00600001, 0x210003be, 0x008d0280, 0x00000000 },
39 	{ 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 },
40 	{ 0x05800031, 0x24001cc8, 0x00000040, 0x90019000 },
41 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
42 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
43 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
44 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
45 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
46 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
47 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
48 	{ 0x0000007e, 0x00000000, 0x00000000, 0x00000000 },
49 };
50 
51 static uint32_t
batch_round_upto(struct intel_batchbuffer * batch,uint32_t divisor)52 batch_round_upto(struct intel_batchbuffer *batch, uint32_t divisor)
53 {
54 	uint32_t offset = batch->ptr - batch->buffer;
55 
56 	offset = (offset + divisor-1) / divisor * divisor;
57 	batch->ptr = batch->buffer + offset;
58 	return offset;
59 }
60 
61 static void
gen6_render_flush(struct intel_batchbuffer * batch,drm_intel_context * context,uint32_t batch_end)62 gen6_render_flush(struct intel_batchbuffer *batch,
63 		  drm_intel_context *context, uint32_t batch_end)
64 {
65 	int ret;
66 
67 	ret = drm_intel_bo_subdata(batch->bo, 0, 4096, batch->buffer);
68 	if (ret == 0)
69 		ret = drm_intel_gem_bo_context_exec(batch->bo, context,
70 						    batch_end, 0);
71 	igt_assert(ret == 0);
72 }
73 
74 static uint32_t
gen6_bind_buf(struct intel_batchbuffer * batch,const struct igt_buf * buf,int is_dst)75 gen6_bind_buf(struct intel_batchbuffer *batch, const struct igt_buf *buf,
76 	      int is_dst)
77 {
78 	struct gen6_surface_state *ss;
79 	uint32_t write_domain, read_domain;
80 	int ret;
81 
82 	igt_assert_lte(buf->stride, 128*1024);
83 	igt_assert_lte(igt_buf_width(buf), 8192);
84 	igt_assert_lte(igt_buf_height(buf), 8192);
85 
86 	if (is_dst) {
87 		write_domain = read_domain = I915_GEM_DOMAIN_RENDER;
88 	} else {
89 		write_domain = 0;
90 		read_domain = I915_GEM_DOMAIN_SAMPLER;
91 	}
92 
93 	ss = intel_batchbuffer_subdata_alloc(batch, sizeof(*ss), 32);
94 	ss->ss0.surface_type = SURFACE_2D;
95 
96 	switch (buf->bpp) {
97 		case 8: ss->ss0.surface_format = SURFACEFORMAT_R8_UNORM; break;
98 		case 16: ss->ss0.surface_format = SURFACEFORMAT_R8G8_UNORM; break;
99 		case 32: ss->ss0.surface_format = SURFACEFORMAT_B8G8R8A8_UNORM; break;
100 		case 64: ss->ss0.surface_format = SURFACEFORMAT_R16G16B16A16_FLOAT; break;
101 		default: igt_assert(0);
102 	}
103 
104 	ss->ss0.data_return_format = SURFACERETURNFORMAT_FLOAT32;
105 	ss->ss0.color_blend = 1;
106 	ss->ss1.base_addr = buf->bo->offset;
107 
108 	ret = drm_intel_bo_emit_reloc(batch->bo,
109 				      intel_batchbuffer_subdata_offset(batch, &ss->ss1),
110 				      buf->bo, 0,
111 				      read_domain, write_domain);
112 	igt_assert(ret == 0);
113 
114 	ss->ss2.height = igt_buf_height(buf) - 1;
115 	ss->ss2.width  = igt_buf_width(buf) - 1;
116 	ss->ss3.pitch  = buf->stride - 1;
117 	ss->ss3.tiled_surface = buf->tiling != I915_TILING_NONE;
118 	ss->ss3.tile_walk     = buf->tiling == I915_TILING_Y;
119 
120 	ss->ss5.memory_object_control = GEN6_MOCS_PTE;
121 
122 	return intel_batchbuffer_subdata_offset(batch, ss);
123 }
124 
125 static uint32_t
gen6_bind_surfaces(struct intel_batchbuffer * batch,const struct igt_buf * src,const struct igt_buf * dst)126 gen6_bind_surfaces(struct intel_batchbuffer *batch,
127 		   const struct igt_buf *src,
128 		   const struct igt_buf *dst)
129 {
130 	uint32_t *binding_table;
131 
132 	binding_table = intel_batchbuffer_subdata_alloc(batch, 32, 32);
133 
134 	binding_table[0] = gen6_bind_buf(batch, dst, 1);
135 	binding_table[1] = gen6_bind_buf(batch, src, 0);
136 
137 	return intel_batchbuffer_subdata_offset(batch, binding_table);
138 }
139 
140 static void
gen6_emit_sip(struct intel_batchbuffer * batch)141 gen6_emit_sip(struct intel_batchbuffer *batch)
142 {
143 	OUT_BATCH(GEN4_STATE_SIP | 0);
144 	OUT_BATCH(0);
145 }
146 
147 static void
gen6_emit_urb(struct intel_batchbuffer * batch)148 gen6_emit_urb(struct intel_batchbuffer *batch)
149 {
150 	OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
151 	OUT_BATCH((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT |
152 		  24 << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT); /* at least 24 on GEN6 */
153 	OUT_BATCH(0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT |
154 		  0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT); /* no GS thread */
155 }
156 
157 static void
gen6_emit_state_base_address(struct intel_batchbuffer * batch)158 gen6_emit_state_base_address(struct intel_batchbuffer *batch)
159 {
160 	OUT_BATCH(GEN4_STATE_BASE_ADDRESS | (10 - 2));
161 	OUT_BATCH(0); /* general */
162 	OUT_RELOC(batch->bo, /* surface */
163 		  I915_GEM_DOMAIN_INSTRUCTION, 0,
164 		  BASE_ADDRESS_MODIFY);
165 	OUT_RELOC(batch->bo, /* instruction */
166 		  I915_GEM_DOMAIN_INSTRUCTION, 0,
167 		  BASE_ADDRESS_MODIFY);
168 	OUT_BATCH(0); /* indirect */
169 	OUT_RELOC(batch->bo, /* dynamic */
170 		  I915_GEM_DOMAIN_INSTRUCTION, 0,
171 		  BASE_ADDRESS_MODIFY);
172 
173 	/* upper bounds, disable */
174 	OUT_BATCH(0);
175 	OUT_BATCH(BASE_ADDRESS_MODIFY);
176 	OUT_BATCH(0);
177 	OUT_BATCH(BASE_ADDRESS_MODIFY);
178 }
179 
180 static void
gen6_emit_viewports(struct intel_batchbuffer * batch,uint32_t cc_vp)181 gen6_emit_viewports(struct intel_batchbuffer *batch, uint32_t cc_vp)
182 {
183 	OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
184 		  GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
185 		  (4 - 2));
186 	OUT_BATCH(0);
187 	OUT_BATCH(0);
188 	OUT_BATCH(cc_vp);
189 }
190 
191 static void
gen6_emit_vs(struct intel_batchbuffer * batch)192 gen6_emit_vs(struct intel_batchbuffer *batch)
193 {
194 	/* disable VS constant buffer */
195 	OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
196 	OUT_BATCH(0);
197 	OUT_BATCH(0);
198 	OUT_BATCH(0);
199 	OUT_BATCH(0);
200 
201 	OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
202 	OUT_BATCH(0); /* no VS kernel */
203 	OUT_BATCH(0);
204 	OUT_BATCH(0);
205 	OUT_BATCH(0);
206 	OUT_BATCH(0); /* pass-through */
207 }
208 
209 static void
gen6_emit_gs(struct intel_batchbuffer * batch)210 gen6_emit_gs(struct intel_batchbuffer *batch)
211 {
212 	/* disable GS constant buffer */
213 	OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
214 	OUT_BATCH(0);
215 	OUT_BATCH(0);
216 	OUT_BATCH(0);
217 	OUT_BATCH(0);
218 
219 	OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
220 	OUT_BATCH(0); /* no GS kernel */
221 	OUT_BATCH(0);
222 	OUT_BATCH(0);
223 	OUT_BATCH(0);
224 	OUT_BATCH(0);
225 	OUT_BATCH(0); /* pass-through */
226 }
227 
228 static void
gen6_emit_clip(struct intel_batchbuffer * batch)229 gen6_emit_clip(struct intel_batchbuffer *batch)
230 {
231 	OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
232 	OUT_BATCH(0);
233 	OUT_BATCH(0); /* pass-through */
234 	OUT_BATCH(0);
235 }
236 
237 static void
gen6_emit_wm_constants(struct intel_batchbuffer * batch)238 gen6_emit_wm_constants(struct intel_batchbuffer *batch)
239 {
240 	/* disable WM constant buffer */
241 	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
242 	OUT_BATCH(0);
243 	OUT_BATCH(0);
244 	OUT_BATCH(0);
245 	OUT_BATCH(0);
246 }
247 
248 static void
gen6_emit_null_depth_buffer(struct intel_batchbuffer * batch)249 gen6_emit_null_depth_buffer(struct intel_batchbuffer *batch)
250 {
251 	OUT_BATCH(GEN4_3DSTATE_DEPTH_BUFFER | (7 - 2));
252 	OUT_BATCH(SURFACE_NULL << GEN4_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
253 		  GEN4_DEPTHFORMAT_D32_FLOAT << GEN4_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
254 	OUT_BATCH(0);
255 	OUT_BATCH(0);
256 	OUT_BATCH(0);
257 	OUT_BATCH(0);
258 	OUT_BATCH(0);
259 
260 	OUT_BATCH(GEN4_3DSTATE_CLEAR_PARAMS | (2 - 2));
261 	OUT_BATCH(0);
262 }
263 
264 static void
gen6_emit_invariant(struct intel_batchbuffer * batch)265 gen6_emit_invariant(struct intel_batchbuffer *batch)
266 {
267 	OUT_BATCH(G4X_PIPELINE_SELECT | PIPELINE_SELECT_3D);
268 
269 	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
270 	OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
271 		  GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
272 	OUT_BATCH(0);
273 
274 	OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
275 	OUT_BATCH(1);
276 }
277 
278 static void
gen6_emit_cc(struct intel_batchbuffer * batch,uint32_t blend)279 gen6_emit_cc(struct intel_batchbuffer *batch, uint32_t blend)
280 {
281 	OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
282 	OUT_BATCH(blend | 1);
283 	OUT_BATCH(1024 | 1);
284 	OUT_BATCH(1024 | 1);
285 }
286 
287 static void
gen6_emit_sampler(struct intel_batchbuffer * batch,uint32_t state)288 gen6_emit_sampler(struct intel_batchbuffer *batch, uint32_t state)
289 {
290 	OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
291 		  GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
292 		  (4 - 2));
293 	OUT_BATCH(0); /* VS */
294 	OUT_BATCH(0); /* GS */
295 	OUT_BATCH(state);
296 }
297 
298 static void
gen6_emit_sf(struct intel_batchbuffer * batch)299 gen6_emit_sf(struct intel_batchbuffer *batch)
300 {
301 	OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
302 	OUT_BATCH(1 << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
303 		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
304 		  1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
305 	OUT_BATCH(0);
306 	OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
307 	OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
308 	OUT_BATCH(0);
309 	OUT_BATCH(0);
310 	OUT_BATCH(0);
311 	OUT_BATCH(0);
312 	OUT_BATCH(0); /* DW9 */
313 	OUT_BATCH(0);
314 	OUT_BATCH(0);
315 	OUT_BATCH(0);
316 	OUT_BATCH(0);
317 	OUT_BATCH(0); /* DW14 */
318 	OUT_BATCH(0);
319 	OUT_BATCH(0);
320 	OUT_BATCH(0);
321 	OUT_BATCH(0);
322 	OUT_BATCH(0); /* DW19 */
323 }
324 
325 static void
gen6_emit_wm(struct intel_batchbuffer * batch,int kernel)326 gen6_emit_wm(struct intel_batchbuffer *batch, int kernel)
327 {
328 	OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
329 	OUT_BATCH(kernel);
330 	OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
331 		  2 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
332 	OUT_BATCH(0);
333 	OUT_BATCH(6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT); /* DW4 */
334 	OUT_BATCH((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
335 		  GEN6_3DSTATE_WM_DISPATCH_ENABLE |
336 		  GEN6_3DSTATE_WM_16_DISPATCH_ENABLE);
337 	OUT_BATCH(1 << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
338 		  GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
339 	OUT_BATCH(0);
340 	OUT_BATCH(0);
341 }
342 
343 static void
gen6_emit_binding_table(struct intel_batchbuffer * batch,uint32_t wm_table)344 gen6_emit_binding_table(struct intel_batchbuffer *batch, uint32_t wm_table)
345 {
346 	OUT_BATCH(GEN4_3DSTATE_BINDING_TABLE_POINTERS |
347 		  GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
348 		  (4 - 2));
349 	OUT_BATCH(0);		/* vs */
350 	OUT_BATCH(0);		/* gs */
351 	OUT_BATCH(wm_table);
352 }
353 
354 static void
gen6_emit_drawing_rectangle(struct intel_batchbuffer * batch,const struct igt_buf * dst)355 gen6_emit_drawing_rectangle(struct intel_batchbuffer *batch, const struct igt_buf *dst)
356 {
357 	OUT_BATCH(GEN4_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
358 	OUT_BATCH(0);
359 	OUT_BATCH((igt_buf_height(dst) - 1) << 16 | (igt_buf_width(dst) - 1));
360 	OUT_BATCH(0);
361 }
362 
363 static void
gen6_emit_vertex_elements(struct intel_batchbuffer * batch)364 gen6_emit_vertex_elements(struct intel_batchbuffer *batch)
365 {
366 	/* The VUE layout
367 	 *    dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
368 	 *    dword 4-7: position (x, y, 1.0, 1.0),
369 	 *    dword 8-11: texture coordinate 0 (u0, v0, 0, 0)
370 	 *
371 	 * dword 4-11 are fetched from vertex buffer
372 	 */
373 	OUT_BATCH(GEN4_3DSTATE_VERTEX_ELEMENTS | (2 * 3 + 1 - 2));
374 
375 	OUT_BATCH(0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN6_VE0_VALID |
376 		  SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
377 		  0 << VE0_OFFSET_SHIFT);
378 	OUT_BATCH(GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
379 		  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
380 		  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
381 		  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
382 
383 	/* x,y */
384 	OUT_BATCH(0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN6_VE0_VALID |
385 		  SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
386 		  0 << VE0_OFFSET_SHIFT); /* offsets vb in bytes */
387 	OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
388 		  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
389 		  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
390 		  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
391 
392 	/* u0, v0 */
393 	OUT_BATCH(0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN6_VE0_VALID |
394 		  SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT |
395 		  4 << VE0_OFFSET_SHIFT);	/* offset vb in bytes */
396 	OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
397 		  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
398 		  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
399 		  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
400 }
401 
402 static uint32_t
gen6_create_cc_viewport(struct intel_batchbuffer * batch)403 gen6_create_cc_viewport(struct intel_batchbuffer *batch)
404 {
405 	struct gen4_cc_viewport *vp;
406 
407 	vp = intel_batchbuffer_subdata_alloc(batch, sizeof(*vp), 32);
408 
409 	vp->min_depth = -1.e35;
410 	vp->max_depth = 1.e35;
411 
412 	return intel_batchbuffer_subdata_offset(batch, vp);
413 }
414 
415 static uint32_t
gen6_create_cc_blend(struct intel_batchbuffer * batch)416 gen6_create_cc_blend(struct intel_batchbuffer *batch)
417 {
418 	struct gen6_blend_state *blend;
419 
420 	blend = intel_batchbuffer_subdata_alloc(batch, sizeof(*blend), 64);
421 
422 	blend->blend0.dest_blend_factor = GEN6_BLENDFACTOR_ZERO;
423 	blend->blend0.source_blend_factor = GEN6_BLENDFACTOR_ONE;
424 	blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
425 	blend->blend0.blend_enable = 1;
426 
427 	blend->blend1.post_blend_clamp_enable = 1;
428 	blend->blend1.pre_blend_clamp_enable = 1;
429 
430 	return intel_batchbuffer_subdata_offset(batch, blend);
431 }
432 
433 static uint32_t
gen6_create_kernel(struct intel_batchbuffer * batch)434 gen6_create_kernel(struct intel_batchbuffer *batch)
435 {
436 	return intel_batchbuffer_copy_data(batch, ps_kernel_nomask_affine,
437 			  sizeof(ps_kernel_nomask_affine),
438 			  64);
439 }
440 
441 static uint32_t
gen6_create_sampler(struct intel_batchbuffer * batch,sampler_filter_t filter,sampler_extend_t extend)442 gen6_create_sampler(struct intel_batchbuffer *batch,
443 		    sampler_filter_t filter,
444 		   sampler_extend_t extend)
445 {
446 	struct gen6_sampler_state *ss;
447 
448 	ss = intel_batchbuffer_subdata_alloc(batch, sizeof(*ss), 32);
449 	ss->ss0.lod_preclamp = 1;	/* GL mode */
450 
451 	/* We use the legacy mode to get the semantics specified by
452 	 * the Render extension. */
453 	ss->ss0.border_color_mode = GEN4_BORDER_COLOR_MODE_LEGACY;
454 
455 	switch (filter) {
456 	default:
457 	case SAMPLER_FILTER_NEAREST:
458 		ss->ss0.min_filter = GEN4_MAPFILTER_NEAREST;
459 		ss->ss0.mag_filter = GEN4_MAPFILTER_NEAREST;
460 		break;
461 	case SAMPLER_FILTER_BILINEAR:
462 		ss->ss0.min_filter = GEN4_MAPFILTER_LINEAR;
463 		ss->ss0.mag_filter = GEN4_MAPFILTER_LINEAR;
464 		break;
465 	}
466 
467 	switch (extend) {
468 	default:
469 	case SAMPLER_EXTEND_NONE:
470 		ss->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
471 		ss->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
472 		ss->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
473 		break;
474 	case SAMPLER_EXTEND_REPEAT:
475 		ss->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
476 		ss->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
477 		ss->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
478 		break;
479 	case SAMPLER_EXTEND_PAD:
480 		ss->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
481 		ss->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
482 		ss->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
483 		break;
484 	case SAMPLER_EXTEND_REFLECT:
485 		ss->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
486 		ss->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
487 		ss->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
488 		break;
489 	}
490 
491 	return intel_batchbuffer_subdata_offset(batch, ss);
492 }
493 
gen6_emit_vertex_buffer(struct intel_batchbuffer * batch)494 static void gen6_emit_vertex_buffer(struct intel_batchbuffer *batch)
495 {
496 	OUT_BATCH(GEN4_3DSTATE_VERTEX_BUFFERS | 3);
497 	OUT_BATCH(GEN6_VB0_VERTEXDATA |
498 		  0 << GEN6_VB0_BUFFER_INDEX_SHIFT |
499 		  VERTEX_SIZE << VB0_BUFFER_PITCH_SHIFT);
500 	OUT_RELOC(batch->bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
501 	OUT_RELOC(batch->bo, I915_GEM_DOMAIN_VERTEX, 0, batch->bo->size-1);
502 	OUT_BATCH(0);
503 }
504 
gen6_emit_primitive(struct intel_batchbuffer * batch)505 static uint32_t gen6_emit_primitive(struct intel_batchbuffer *batch)
506 {
507 	uint32_t offset;
508 
509 	OUT_BATCH(GEN4_3DPRIMITIVE |
510 		  GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL |
511 		  _3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT |
512 		  0 << 9 |
513 		  4);
514 	OUT_BATCH(3);	/* vertex count */
515 	offset = batch->ptr - batch->buffer;
516 	OUT_BATCH(0);	/* vertex_index */
517 	OUT_BATCH(1);	/* single instance */
518 	OUT_BATCH(0);	/* start instance location */
519 	OUT_BATCH(0);	/* index buffer offset, ignored */
520 
521 	return offset;
522 }
523 
gen6_render_copyfunc(struct intel_batchbuffer * batch,drm_intel_context * context,const struct igt_buf * src,unsigned src_x,unsigned src_y,unsigned width,unsigned height,const struct igt_buf * dst,unsigned dst_x,unsigned dst_y)524 void gen6_render_copyfunc(struct intel_batchbuffer *batch,
525 			  drm_intel_context *context,
526 			  const struct igt_buf *src, unsigned src_x, unsigned src_y,
527 			  unsigned width, unsigned height,
528 			  const struct igt_buf *dst, unsigned dst_x, unsigned dst_y)
529 {
530 	uint32_t wm_state, wm_kernel, wm_table;
531 	uint32_t cc_vp, cc_blend, offset;
532 	uint32_t batch_end;
533 
534 	igt_assert(src->bpp == dst->bpp);
535 	intel_batchbuffer_flush_with_context(batch, context);
536 
537 	batch->ptr = batch->buffer + 1024;
538 	intel_batchbuffer_subdata_alloc(batch, 64, 64);
539 	wm_table  = gen6_bind_surfaces(batch, src, dst);
540 	wm_kernel = gen6_create_kernel(batch);
541 	wm_state  = gen6_create_sampler(batch,
542 					SAMPLER_FILTER_NEAREST,
543 					SAMPLER_EXTEND_NONE);
544 
545 	cc_vp = gen6_create_cc_viewport(batch);
546 	cc_blend = gen6_create_cc_blend(batch);
547 
548 	batch->ptr = batch->buffer;
549 
550 	gen6_emit_invariant(batch);
551 	gen6_emit_state_base_address(batch);
552 
553 	gen6_emit_sip(batch);
554 	gen6_emit_urb(batch);
555 
556 	gen6_emit_viewports(batch, cc_vp);
557 	gen6_emit_vs(batch);
558 	gen6_emit_gs(batch);
559 	gen6_emit_clip(batch);
560 	gen6_emit_wm_constants(batch);
561 	gen6_emit_null_depth_buffer(batch);
562 
563 	gen6_emit_drawing_rectangle(batch, dst);
564 	gen6_emit_cc(batch, cc_blend);
565 	gen6_emit_sampler(batch, wm_state);
566 	gen6_emit_sf(batch);
567 	gen6_emit_wm(batch, wm_kernel);
568 	gen6_emit_vertex_elements(batch);
569 	gen6_emit_binding_table(batch, wm_table);
570 
571 	gen6_emit_vertex_buffer(batch);
572 	offset = gen6_emit_primitive(batch);
573 
574 	OUT_BATCH(MI_BATCH_BUFFER_END);
575 	batch_end = intel_batchbuffer_align(batch, 8);
576 
577 	*(uint32_t*)(batch->buffer + offset) =
578 		batch_round_upto(batch, VERTEX_SIZE)/VERTEX_SIZE;
579 
580 	emit_vertex_2s(batch, dst_x + width, dst_y + height);
581 	emit_vertex_normalized(batch, src_x + width, igt_buf_width(src));
582 	emit_vertex_normalized(batch, src_y + height, igt_buf_height(src));
583 
584 	emit_vertex_2s(batch, dst_x, dst_y + height);
585 	emit_vertex_normalized(batch, src_x, igt_buf_width(src));
586 	emit_vertex_normalized(batch, src_y + height, igt_buf_height(src));
587 
588 	emit_vertex_2s(batch, dst_x, dst_y);
589 	emit_vertex_normalized(batch, src_x, igt_buf_width(src));
590 	emit_vertex_normalized(batch, src_y, igt_buf_height(src));
591 
592 	gen6_render_flush(batch, context, batch_end);
593 	intel_batchbuffer_reset(batch);
594 }
595