blob: 8c24cf8adf84d27d5cab947f66c3ceb0fa57dbe0 [file] [log] [blame]
Daniel Vetter7dc00012014-03-22 15:31:15 +01001#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>
Daniel Vetter7dc00012014-03-22 15:31:15 +010012#include "drm.h"
13#include "i915_drm.h"
14#include "drmtest.h"
15#include "intel_bufmgr.h"
16#include "intel_batchbuffer.h"
Daniel Vetterc03c6ce2014-03-22 21:34:29 +010017#include "intel_io.h"
Daniel Vetter13574272012-01-18 17:53:12 +010018#include "rendercopy.h"
Chris Wilson719ffef2011-05-22 10:34:12 +010019#include "gen6_render.h"
Daniel Vetter6cfcd712014-03-22 20:07:35 +010020#include "intel_reg.h"
Chris Wilson719ffef2011-05-22 10:34:12 +010021
Chris Wilson719ffef2011-05-22 10:34:12 +010022#define VERTEX_SIZE (3*4)
23
24static 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
51static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +010052batch_used(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +010053{
54 return batch->ptr - batch->buffer;
55}
56
57static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +010058batch_align(struct intel_batchbuffer *batch, uint32_t align)
Chris Wilson719ffef2011-05-22 10:34:12 +010059{
Daniel Vetterf1de2852012-01-18 00:55:49 +010060 uint32_t offset = batch_used(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +010061 offset = ALIGN(offset, align);
62 batch->ptr = batch->buffer + offset;
63 return offset;
64}
65
66static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +010067batch_round_upto(struct intel_batchbuffer *batch, uint32_t divisor)
Chris Wilson719ffef2011-05-22 10:34:12 +010068{
Daniel Vetterf1de2852012-01-18 00:55:49 +010069 uint32_t offset = batch_used(batch);
Daniel Vettera7a80c22012-01-10 15:50:20 +010070 offset = (offset + divisor-1) / divisor * divisor;
Chris Wilson719ffef2011-05-22 10:34:12 +010071 batch->ptr = batch->buffer + offset;
72 return offset;
73}
74
75static void *
Daniel Vetterf1de2852012-01-18 00:55:49 +010076batch_alloc(struct intel_batchbuffer *batch, uint32_t size, uint32_t align)
Chris Wilson719ffef2011-05-22 10:34:12 +010077{
Daniel Vetterf1de2852012-01-18 00:55:49 +010078 uint32_t offset = batch_align(batch, align);
Chris Wilson719ffef2011-05-22 10:34:12 +010079 batch->ptr += size;
80 return memset(batch->buffer + offset, 0, size);
81}
82
83static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +010084batch_offset(struct intel_batchbuffer *batch, void *ptr)
Chris Wilson719ffef2011-05-22 10:34:12 +010085{
86 return (uint8_t *)ptr - batch->buffer;
87}
88
89static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +010090batch_copy(struct intel_batchbuffer *batch, const void *ptr, uint32_t size, uint32_t align)
Chris Wilson719ffef2011-05-22 10:34:12 +010091{
Daniel Vetterf1de2852012-01-18 00:55:49 +010092 return batch_offset(batch, memcpy(batch_alloc(batch, size, align), ptr, size));
Chris Wilson719ffef2011-05-22 10:34:12 +010093}
94
95static void
Ville Syrjälä725da6e2013-11-21 19:05:17 +020096gen6_render_flush(struct intel_batchbuffer *batch,
97 drm_intel_context *context, uint32_t batch_end)
Chris Wilson719ffef2011-05-22 10:34:12 +010098{
99 int ret;
100
101 ret = drm_intel_bo_subdata(batch->bo, 0, 4096, batch->buffer);
102 if (ret == 0)
Ville Syrjälä725da6e2013-11-21 19:05:17 +0200103 ret = drm_intel_gem_bo_context_exec(batch->bo, context,
104 batch_end, 0);
Daniel Vetterbaa6f8b2014-08-26 15:03:40 +0200105 igt_assert(ret == 0);
Chris Wilson719ffef2011-05-22 10:34:12 +0100106}
107
108static uint32_t
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100109gen6_bind_buf(struct intel_batchbuffer *batch, struct igt_buf *buf,
Chris Wilson719ffef2011-05-22 10:34:12 +0100110 uint32_t format, int is_dst)
111{
112 struct gen6_surface_state *ss;
113 uint32_t write_domain, read_domain;
114 int ret;
115
116 if (is_dst) {
117 write_domain = read_domain = I915_GEM_DOMAIN_RENDER;
118 } else {
119 write_domain = 0;
120 read_domain = I915_GEM_DOMAIN_SAMPLER;
121 }
122
Daniel Vetterf1de2852012-01-18 00:55:49 +0100123 ss = batch_alloc(batch, sizeof(*ss), 32);
Chris Wilson719ffef2011-05-22 10:34:12 +0100124 ss->ss0.surface_type = GEN6_SURFACE_2D;
125 ss->ss0.surface_format = format;
126
127 ss->ss0.data_return_format = GEN6_SURFACERETURNFORMAT_FLOAT32;
128 ss->ss0.color_blend = 1;
129 ss->ss1.base_addr = buf->bo->offset;
130
131 ret = drm_intel_bo_emit_reloc(batch->bo,
Daniel Vetterf1de2852012-01-18 00:55:49 +0100132 batch_offset(batch, ss) + 4,
Chris Wilson719ffef2011-05-22 10:34:12 +0100133 buf->bo, 0,
134 read_domain, write_domain);
Daniel Vetterbaa6f8b2014-08-26 15:03:40 +0200135 igt_assert(ret == 0);
Chris Wilson719ffef2011-05-22 10:34:12 +0100136
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100137 ss->ss2.height = igt_buf_height(buf) - 1;
138 ss->ss2.width = igt_buf_width(buf) - 1;
Chris Wilson719ffef2011-05-22 10:34:12 +0100139 ss->ss3.pitch = buf->stride - 1;
140 ss->ss3.tiled_surface = buf->tiling != I915_TILING_NONE;
141 ss->ss3.tile_walk = buf->tiling == I915_TILING_Y;
142
Daniel Vetterf1de2852012-01-18 00:55:49 +0100143 return batch_offset(batch, ss);
Chris Wilson719ffef2011-05-22 10:34:12 +0100144}
145
146static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +0100147gen6_bind_surfaces(struct intel_batchbuffer *batch,
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100148 struct igt_buf *src,
149 struct igt_buf *dst)
Chris Wilson719ffef2011-05-22 10:34:12 +0100150{
151 uint32_t *binding_table;
152
Daniel Vetterf1de2852012-01-18 00:55:49 +0100153 binding_table = batch_alloc(batch, 32, 32);
Chris Wilson719ffef2011-05-22 10:34:12 +0100154
155 binding_table[0] =
Daniel Vetterf1de2852012-01-18 00:55:49 +0100156 gen6_bind_buf(batch, dst, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 1);
Chris Wilson719ffef2011-05-22 10:34:12 +0100157 binding_table[1] =
Daniel Vetterf1de2852012-01-18 00:55:49 +0100158 gen6_bind_buf(batch, src, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, 0);
Chris Wilson719ffef2011-05-22 10:34:12 +0100159
Daniel Vetterf1de2852012-01-18 00:55:49 +0100160 return batch_offset(batch, binding_table);
Chris Wilson719ffef2011-05-22 10:34:12 +0100161}
162
163static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100164gen6_emit_sip(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100165{
166 OUT_BATCH(GEN6_STATE_SIP | 0);
167 OUT_BATCH(0);
168}
169
170static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100171gen6_emit_urb(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100172{
173 OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2));
174 OUT_BATCH((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT |
175 24 << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT); /* at least 24 on GEN6 */
176 OUT_BATCH(0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT |
177 0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT); /* no GS thread */
178}
179
180static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100181gen6_emit_state_base_address(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100182{
183 OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2));
184 OUT_BATCH(0); /* general */
185 OUT_RELOC(batch->bo, /* surface */
186 I915_GEM_DOMAIN_INSTRUCTION, 0,
187 BASE_ADDRESS_MODIFY);
188 OUT_RELOC(batch->bo, /* instruction */
189 I915_GEM_DOMAIN_INSTRUCTION, 0,
190 BASE_ADDRESS_MODIFY);
191 OUT_BATCH(0); /* indirect */
192 OUT_RELOC(batch->bo, /* dynamic */
193 I915_GEM_DOMAIN_INSTRUCTION, 0,
194 BASE_ADDRESS_MODIFY);
195
196 /* upper bounds, disable */
197 OUT_BATCH(0);
198 OUT_BATCH(BASE_ADDRESS_MODIFY);
199 OUT_BATCH(0);
200 OUT_BATCH(BASE_ADDRESS_MODIFY);
201}
202
203static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100204gen6_emit_viewports(struct intel_batchbuffer *batch, uint32_t cc_vp)
Chris Wilson719ffef2011-05-22 10:34:12 +0100205{
206 OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS |
207 GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC |
208 (4 - 2));
209 OUT_BATCH(0);
210 OUT_BATCH(0);
211 OUT_BATCH(cc_vp);
212}
213
214static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100215gen6_emit_vs(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100216{
217 /* disable VS constant buffer */
218 OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2));
219 OUT_BATCH(0);
220 OUT_BATCH(0);
221 OUT_BATCH(0);
222 OUT_BATCH(0);
223
224 OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2));
225 OUT_BATCH(0); /* no VS kernel */
226 OUT_BATCH(0);
227 OUT_BATCH(0);
228 OUT_BATCH(0);
229 OUT_BATCH(0); /* pass-through */
230}
231
232static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100233gen6_emit_gs(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100234{
235 /* disable GS constant buffer */
236 OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2));
237 OUT_BATCH(0);
238 OUT_BATCH(0);
239 OUT_BATCH(0);
240 OUT_BATCH(0);
241
242 OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2));
243 OUT_BATCH(0); /* no GS kernel */
244 OUT_BATCH(0);
245 OUT_BATCH(0);
246 OUT_BATCH(0);
247 OUT_BATCH(0);
248 OUT_BATCH(0); /* pass-through */
249}
250
251static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100252gen6_emit_clip(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100253{
254 OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2));
255 OUT_BATCH(0);
256 OUT_BATCH(0); /* pass-through */
257 OUT_BATCH(0);
258}
259
260static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100261gen6_emit_wm_constants(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100262{
263 /* disable WM constant buffer */
264 OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2));
265 OUT_BATCH(0);
266 OUT_BATCH(0);
267 OUT_BATCH(0);
268 OUT_BATCH(0);
269}
270
271static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100272gen6_emit_null_depth_buffer(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100273{
274 OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2));
275 OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT |
276 GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT);
277 OUT_BATCH(0);
278 OUT_BATCH(0);
279 OUT_BATCH(0);
280 OUT_BATCH(0);
281 OUT_BATCH(0);
282
283 OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2));
284 OUT_BATCH(0);
285}
286
287static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100288gen6_emit_invariant(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100289{
290 OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D);
291
292 OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2));
293 OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
294 GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
295 OUT_BATCH(0);
296
297 OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
298 OUT_BATCH(1);
299}
300
301static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100302gen6_emit_cc(struct intel_batchbuffer *batch, uint32_t blend)
Chris Wilson719ffef2011-05-22 10:34:12 +0100303{
304 OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2));
305 OUT_BATCH(blend | 1);
306 OUT_BATCH(1024 | 1);
307 OUT_BATCH(1024 | 1);
308}
309
310static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100311gen6_emit_sampler(struct intel_batchbuffer *batch, uint32_t state)
Chris Wilson719ffef2011-05-22 10:34:12 +0100312{
313 OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS |
314 GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS |
315 (4 - 2));
316 OUT_BATCH(0); /* VS */
317 OUT_BATCH(0); /* GS */
318 OUT_BATCH(state);
319}
320
321static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100322gen6_emit_sf(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100323{
324 OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2));
325 OUT_BATCH(1 << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT |
326 1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT |
327 1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT);
328 OUT_BATCH(0);
329 OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE);
330 OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */
331 OUT_BATCH(0);
332 OUT_BATCH(0);
333 OUT_BATCH(0);
334 OUT_BATCH(0);
335 OUT_BATCH(0); /* DW9 */
336 OUT_BATCH(0);
337 OUT_BATCH(0);
338 OUT_BATCH(0);
339 OUT_BATCH(0);
340 OUT_BATCH(0); /* DW14 */
341 OUT_BATCH(0);
342 OUT_BATCH(0);
343 OUT_BATCH(0);
344 OUT_BATCH(0);
345 OUT_BATCH(0); /* DW19 */
346}
347
348static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100349gen6_emit_wm(struct intel_batchbuffer *batch, int kernel)
Chris Wilson719ffef2011-05-22 10:34:12 +0100350{
351 OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2));
352 OUT_BATCH(kernel);
353 OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT |
354 2 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT);
355 OUT_BATCH(0);
356 OUT_BATCH(6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT); /* DW4 */
357 OUT_BATCH((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT |
358 GEN6_3DSTATE_WM_DISPATCH_ENABLE |
359 GEN6_3DSTATE_WM_16_DISPATCH_ENABLE);
360 OUT_BATCH(1 << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT |
361 GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
362 OUT_BATCH(0);
363 OUT_BATCH(0);
364}
365
366static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100367gen6_emit_binding_table(struct intel_batchbuffer *batch, uint32_t wm_table)
Chris Wilson719ffef2011-05-22 10:34:12 +0100368{
369 OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS |
370 GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS |
371 (4 - 2));
372 OUT_BATCH(0); /* vs */
373 OUT_BATCH(0); /* gs */
374 OUT_BATCH(wm_table);
375}
376
377static void
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100378gen6_emit_drawing_rectangle(struct intel_batchbuffer *batch, struct igt_buf *dst)
Chris Wilson719ffef2011-05-22 10:34:12 +0100379{
380 OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
381 OUT_BATCH(0);
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100382 OUT_BATCH((igt_buf_height(dst) - 1) << 16 | (igt_buf_width(dst) - 1));
Chris Wilson719ffef2011-05-22 10:34:12 +0100383 OUT_BATCH(0);
384}
385
386static void
Daniel Vetterf1de2852012-01-18 00:55:49 +0100387gen6_emit_vertex_elements(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100388{
389 /* The VUE layout
390 * dword 0-3: pad (0.0, 0.0, 0.0. 0.0)
391 * dword 4-7: position (x, y, 1.0, 1.0),
392 * dword 8-11: texture coordinate 0 (u0, v0, 0, 0)
393 *
394 * dword 4-11 are fetched from vertex buffer
395 */
396 OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS | (2 * 3 + 1 - 2));
397
398 OUT_BATCH(0 << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
399 GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT |
400 0 << VE0_OFFSET_SHIFT);
401 OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
402 GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
403 GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
404 GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
405
406 /* x,y */
407 OUT_BATCH(0 << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
408 GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
409 0 << VE0_OFFSET_SHIFT); /* offsets vb in bytes */
410 OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
411 GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
412 GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
413 GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT);
414
415 /* u0, v0 */
416 OUT_BATCH(0 << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
417 GEN6_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT |
418 4 << VE0_OFFSET_SHIFT); /* offset vb in bytes */
419 OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
420 GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
421 GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
422 GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT);
423}
424
425static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +0100426gen6_create_cc_viewport(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100427{
428 struct gen6_cc_viewport *vp;
429
Daniel Vetterf1de2852012-01-18 00:55:49 +0100430 vp = batch_alloc(batch, sizeof(*vp), 32);
Chris Wilson719ffef2011-05-22 10:34:12 +0100431
432 vp->min_depth = -1.e35;
433 vp->max_depth = 1.e35;
434
Daniel Vetterf1de2852012-01-18 00:55:49 +0100435 return batch_offset(batch, vp);
Chris Wilson719ffef2011-05-22 10:34:12 +0100436}
437
438static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +0100439gen6_create_cc_blend(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100440{
441 struct gen6_blend_state *blend;
442
Daniel Vetterf1de2852012-01-18 00:55:49 +0100443 blend = batch_alloc(batch, sizeof(*blend), 64);
Chris Wilson719ffef2011-05-22 10:34:12 +0100444
445 blend->blend0.dest_blend_factor = GEN6_BLENDFACTOR_ZERO;
446 blend->blend0.source_blend_factor = GEN6_BLENDFACTOR_ONE;
447 blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD;
448 blend->blend0.blend_enable = 1;
449
450 blend->blend1.post_blend_clamp_enable = 1;
451 blend->blend1.pre_blend_clamp_enable = 1;
452
Daniel Vetterf1de2852012-01-18 00:55:49 +0100453 return batch_offset(batch, blend);
Chris Wilson719ffef2011-05-22 10:34:12 +0100454}
455
456static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +0100457gen6_create_kernel(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100458{
Daniel Vetterf1de2852012-01-18 00:55:49 +0100459 return batch_copy(batch, ps_kernel_nomask_affine,
Chris Wilson719ffef2011-05-22 10:34:12 +0100460 sizeof(ps_kernel_nomask_affine),
461 64);
462}
463
464static uint32_t
Daniel Vetterf1de2852012-01-18 00:55:49 +0100465gen6_create_sampler(struct intel_batchbuffer *batch,
466 sampler_filter_t filter,
Chris Wilson719ffef2011-05-22 10:34:12 +0100467 sampler_extend_t extend)
468{
469 struct gen6_sampler_state *ss;
470
Daniel Vetterf1de2852012-01-18 00:55:49 +0100471 ss = batch_alloc(batch, sizeof(*ss), 32);
Chris Wilson719ffef2011-05-22 10:34:12 +0100472 ss->ss0.lod_preclamp = 1; /* GL mode */
473
474 /* We use the legacy mode to get the semantics specified by
475 * the Render extension. */
476 ss->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY;
477
478 switch (filter) {
479 default:
480 case SAMPLER_FILTER_NEAREST:
481 ss->ss0.min_filter = GEN6_MAPFILTER_NEAREST;
482 ss->ss0.mag_filter = GEN6_MAPFILTER_NEAREST;
483 break;
484 case SAMPLER_FILTER_BILINEAR:
485 ss->ss0.min_filter = GEN6_MAPFILTER_LINEAR;
486 ss->ss0.mag_filter = GEN6_MAPFILTER_LINEAR;
487 break;
488 }
489
490 switch (extend) {
491 default:
492 case SAMPLER_EXTEND_NONE:
493 ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
494 ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
495 ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER;
496 break;
497 case SAMPLER_EXTEND_REPEAT:
498 ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
499 ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
500 ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP;
501 break;
502 case SAMPLER_EXTEND_PAD:
503 ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
504 ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
505 ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP;
506 break;
507 case SAMPLER_EXTEND_REFLECT:
508 ss->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
509 ss->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
510 ss->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR;
511 break;
512 }
513
Daniel Vetterf1de2852012-01-18 00:55:49 +0100514 return batch_offset(batch, ss);
Chris Wilson719ffef2011-05-22 10:34:12 +0100515}
516
Daniel Vetterf1de2852012-01-18 00:55:49 +0100517static void gen6_emit_vertex_buffer(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100518{
519 OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3);
520 OUT_BATCH(VB0_VERTEXDATA |
521 0 << VB0_BUFFER_INDEX_SHIFT |
522 VERTEX_SIZE << VB0_BUFFER_PITCH_SHIFT);
523 OUT_RELOC(batch->bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
524 OUT_RELOC(batch->bo, I915_GEM_DOMAIN_VERTEX, 0, batch->bo->size-1);
525 OUT_BATCH(0);
526}
527
Daniel Vetterf1de2852012-01-18 00:55:49 +0100528static uint32_t gen6_emit_primitive(struct intel_batchbuffer *batch)
Chris Wilson719ffef2011-05-22 10:34:12 +0100529{
530 uint32_t offset;
531
532 OUT_BATCH(GEN6_3DPRIMITIVE |
533 GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL |
534 _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT |
535 0 << 9 |
536 4);
537 OUT_BATCH(3); /* vertex count */
Daniel Vetterf1de2852012-01-18 00:55:49 +0100538 offset = batch_used(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100539 OUT_BATCH(0); /* vertex_index */
540 OUT_BATCH(1); /* single instance */
541 OUT_BATCH(0); /* start instance location */
542 OUT_BATCH(0); /* index buffer offset, ignored */
543
544 return offset;
545}
546
Daniel Vetterf1de2852012-01-18 00:55:49 +0100547void gen6_render_copyfunc(struct intel_batchbuffer *batch,
Ville Syrjälä725da6e2013-11-21 19:05:17 +0200548 drm_intel_context *context,
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100549 struct igt_buf *src, unsigned src_x, unsigned src_y,
Daniel Vetter9f20ecc2012-01-18 17:46:00 +0100550 unsigned width, unsigned height,
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100551 struct igt_buf *dst, unsigned dst_x, unsigned dst_y)
Chris Wilson719ffef2011-05-22 10:34:12 +0100552{
553 uint32_t wm_state, wm_kernel, wm_table;
554 uint32_t cc_vp, cc_blend, offset;
555 uint32_t batch_end;
556
Ville Syrjälä725da6e2013-11-21 19:05:17 +0200557 intel_batchbuffer_flush_with_context(batch, context);
Chris Wilson719ffef2011-05-22 10:34:12 +0100558
559 batch->ptr = batch->buffer + 1024;
Daniel Vetterf1de2852012-01-18 00:55:49 +0100560 batch_alloc(batch, 64, 64);
561 wm_table = gen6_bind_surfaces(batch, src, dst);
562 wm_kernel = gen6_create_kernel(batch);
563 wm_state = gen6_create_sampler(batch,
564 SAMPLER_FILTER_NEAREST,
Chris Wilson719ffef2011-05-22 10:34:12 +0100565 SAMPLER_EXTEND_NONE);
566
Daniel Vetterf1de2852012-01-18 00:55:49 +0100567 cc_vp = gen6_create_cc_viewport(batch);
568 cc_blend = gen6_create_cc_blend(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100569
570 batch->ptr = batch->buffer;
571
Daniel Vetterf1de2852012-01-18 00:55:49 +0100572 gen6_emit_invariant(batch);
573 gen6_emit_state_base_address(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100574
Daniel Vetterf1de2852012-01-18 00:55:49 +0100575 gen6_emit_sip(batch);
576 gen6_emit_urb(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100577
Daniel Vetterf1de2852012-01-18 00:55:49 +0100578 gen6_emit_viewports(batch, cc_vp);
579 gen6_emit_vs(batch);
580 gen6_emit_gs(batch);
581 gen6_emit_clip(batch);
582 gen6_emit_wm_constants(batch);
583 gen6_emit_null_depth_buffer(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100584
Daniel Vetterf1de2852012-01-18 00:55:49 +0100585 gen6_emit_drawing_rectangle(batch, dst);
586 gen6_emit_cc(batch, cc_blend);
587 gen6_emit_sampler(batch, wm_state);
588 gen6_emit_sf(batch);
589 gen6_emit_wm(batch, wm_kernel);
590 gen6_emit_vertex_elements(batch);
591 gen6_emit_binding_table(batch, wm_table);
Chris Wilson719ffef2011-05-22 10:34:12 +0100592
Daniel Vetterf1de2852012-01-18 00:55:49 +0100593 gen6_emit_vertex_buffer(batch);
594 offset = gen6_emit_primitive(batch);
Chris Wilson719ffef2011-05-22 10:34:12 +0100595
596 OUT_BATCH(MI_BATCH_BUFFER_END);
Daniel Vetterf1de2852012-01-18 00:55:49 +0100597 batch_end = batch_align(batch, 8);
Chris Wilson719ffef2011-05-22 10:34:12 +0100598
599 *(uint32_t*)(batch->buffer + offset) =
Daniel Vetterf1de2852012-01-18 00:55:49 +0100600 batch_round_upto(batch, VERTEX_SIZE)/VERTEX_SIZE;
Chris Wilson719ffef2011-05-22 10:34:12 +0100601
Daniel Vetter9f20ecc2012-01-18 17:46:00 +0100602 emit_vertex_2s(batch, dst_x + width, dst_y + height);
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100603 emit_vertex_normalized(batch, src_x + width, igt_buf_width(src));
604 emit_vertex_normalized(batch, src_y + height, igt_buf_height(src));
Chris Wilson719ffef2011-05-22 10:34:12 +0100605
Daniel Vetter9f20ecc2012-01-18 17:46:00 +0100606 emit_vertex_2s(batch, dst_x, dst_y + height);
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100607 emit_vertex_normalized(batch, src_x, igt_buf_width(src));
608 emit_vertex_normalized(batch, src_y + height, igt_buf_height(src));
Chris Wilson719ffef2011-05-22 10:34:12 +0100609
Daniel Vetterf1de2852012-01-18 00:55:49 +0100610 emit_vertex_2s(batch, dst_x, dst_y);
Daniel Vetter83a4c7d2014-03-22 15:44:48 +0100611 emit_vertex_normalized(batch, src_x, igt_buf_width(src));
612 emit_vertex_normalized(batch, src_y, igt_buf_height(src));
Chris Wilson719ffef2011-05-22 10:34:12 +0100613
Ville Syrjälä725da6e2013-11-21 19:05:17 +0200614 gen6_render_flush(batch, context, batch_end);
Chris Wilson719ffef2011-05-22 10:34:12 +0100615 intel_batchbuffer_reset(batch);
616}