ilo: fix a buffer overrun
[mesa.git] / src / gallium / drivers / ilo / core / ilo_builder_3d_top.h
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
26 */
27
28 #ifndef ILO_BUILDER_3D_TOP_H
29 #define ILO_BUILDER_3D_TOP_H
30
31 #include "genhw/genhw.h"
32 #include "../ilo_resource.h"
33 #include "../ilo_state.h"
34 #include "intel_winsys.h"
35
36 #include "ilo_core.h"
37 #include "ilo_dev.h"
38 #include "ilo_state_sampler.h"
39 #include "ilo_state_shader.h"
40 #include "ilo_state_sol.h"
41 #include "ilo_state_urb.h"
42 #include "ilo_state_vf.h"
43 #include "ilo_builder.h"
44
45 static inline void
46 gen6_3DSTATE_URB(struct ilo_builder *builder,
47 const struct ilo_state_urb *urb)
48 {
49 const uint8_t cmd_len = 3;
50 uint32_t *dw;
51
52 ilo_builder_batch_pointer(builder, cmd_len, &dw);
53
54 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
55 /* see urb_set_gen6_3DSTATE_URB() */
56 dw[1] = urb->urb[0];
57 dw[2] = urb->urb[1];
58 }
59
60 static inline void
61 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
62 const struct ilo_state_urb *urb)
63 {
64 const uint8_t cmd_len = 2;
65 uint32_t *dw;
66
67 ilo_builder_batch_pointer(builder, cmd_len, &dw);
68
69 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_VS) |
70 (cmd_len - 2);
71 /* see urb_set_gen7_3dstate_push_constant_alloc() */
72 dw[1] = urb->pcb[0];
73 }
74
75 static inline void
76 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
77 const struct ilo_state_urb *urb)
78 {
79 const uint8_t cmd_len = 2;
80 uint32_t *dw;
81
82 ilo_builder_batch_pointer(builder, cmd_len, &dw);
83
84 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_HS) |
85 (cmd_len - 2);
86 /* see urb_set_gen7_3dstate_push_constant_alloc() */
87 dw[1] = urb->pcb[1];
88 }
89
90 static inline void
91 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
92 const struct ilo_state_urb *urb)
93 {
94 const uint8_t cmd_len = 2;
95 uint32_t *dw;
96
97 ilo_builder_batch_pointer(builder, cmd_len, &dw);
98
99 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_DS) |
100 (cmd_len - 2);
101 /* see urb_set_gen7_3dstate_push_constant_alloc() */
102 dw[1] = urb->pcb[2];
103 }
104
105 static inline void
106 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
107 const struct ilo_state_urb *urb)
108 {
109 const uint8_t cmd_len = 2;
110 uint32_t *dw;
111
112 ilo_builder_batch_pointer(builder, cmd_len, &dw);
113
114 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_GS) |
115 (cmd_len - 2);
116 /* see urb_set_gen7_3dstate_push_constant_alloc() */
117 dw[1] = urb->pcb[3];
118 }
119
120 static inline void
121 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
122 const struct ilo_state_urb *urb)
123 {
124 const uint8_t cmd_len = 2;
125 uint32_t *dw;
126
127 ilo_builder_batch_pointer(builder, cmd_len, &dw);
128
129 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_PUSH_CONSTANT_ALLOC_PS) |
130 (cmd_len - 2);
131 /* see urb_set_gen7_3dstate_push_constant_alloc() */
132 dw[1] = urb->pcb[4];
133 }
134
135 static inline void
136 gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
137 const struct ilo_state_urb *urb)
138 {
139 const uint8_t cmd_len = 2;
140 uint32_t *dw;
141
142 ilo_builder_batch_pointer(builder, cmd_len, &dw);
143
144 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_VS) | (cmd_len - 2);
145 /* see urb_set_gen7_3dstate_push_constant_alloc() */
146 dw[1] = urb->urb[0];
147 }
148
149 static inline void
150 gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
151 const struct ilo_state_urb *urb)
152 {
153 const uint8_t cmd_len = 2;
154 uint32_t *dw;
155
156 ilo_builder_batch_pointer(builder, cmd_len, &dw);
157
158 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_HS) | (cmd_len - 2);
159 /* see urb_set_gen7_3dstate_push_constant_alloc() */
160 dw[1] = urb->urb[1];
161 }
162
163 static inline void
164 gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
165 const struct ilo_state_urb *urb)
166 {
167 const uint8_t cmd_len = 2;
168 uint32_t *dw;
169
170 ilo_builder_batch_pointer(builder, cmd_len, &dw);
171
172 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_DS) | (cmd_len - 2);
173 /* see urb_set_gen7_3dstate_push_constant_alloc() */
174 dw[1] = urb->urb[2];
175 }
176
177 static inline void
178 gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
179 const struct ilo_state_urb *urb)
180 {
181 const uint8_t cmd_len = 2;
182 uint32_t *dw;
183
184 ilo_builder_batch_pointer(builder, cmd_len, &dw);
185
186 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_URB_GS) | (cmd_len - 2);
187 /* see urb_set_gen7_3dstate_push_constant_alloc() */
188 dw[1] = urb->urb[3];
189 }
190
191 static inline void
192 gen75_3DSTATE_VF(struct ilo_builder *builder,
193 bool enable_cut_index,
194 uint32_t cut_index)
195 {
196 const uint8_t cmd_len = 2;
197 uint32_t *dw;
198
199 ILO_DEV_ASSERT(builder->dev, 7.5, 8);
200
201 ilo_builder_batch_pointer(builder, cmd_len, &dw);
202
203 dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
204 if (enable_cut_index)
205 dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
206
207 dw[1] = cut_index;
208 }
209
210 static inline void
211 gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
212 bool enable)
213 {
214 const uint8_t cmd_len = 1;
215 const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
216 enable;
217
218 ILO_DEV_ASSERT(builder->dev, 6, 8);
219
220 ilo_builder_batch_write(builder, cmd_len, &dw0);
221 }
222
223 /**
224 * Translate a pipe primitive type to the matching hardware primitive type.
225 */
226 static inline int
227 gen6_3d_translate_pipe_prim(unsigned prim)
228 {
229 static const int prim_mapping[ILO_PRIM_MAX] = {
230 [PIPE_PRIM_POINTS] = GEN6_3DPRIM_POINTLIST,
231 [PIPE_PRIM_LINES] = GEN6_3DPRIM_LINELIST,
232 [PIPE_PRIM_LINE_LOOP] = GEN6_3DPRIM_LINELOOP,
233 [PIPE_PRIM_LINE_STRIP] = GEN6_3DPRIM_LINESTRIP,
234 [PIPE_PRIM_TRIANGLES] = GEN6_3DPRIM_TRILIST,
235 [PIPE_PRIM_TRIANGLE_STRIP] = GEN6_3DPRIM_TRISTRIP,
236 [PIPE_PRIM_TRIANGLE_FAN] = GEN6_3DPRIM_TRIFAN,
237 [PIPE_PRIM_QUADS] = GEN6_3DPRIM_QUADLIST,
238 [PIPE_PRIM_QUAD_STRIP] = GEN6_3DPRIM_QUADSTRIP,
239 [PIPE_PRIM_POLYGON] = GEN6_3DPRIM_POLYGON,
240 [PIPE_PRIM_LINES_ADJACENCY] = GEN6_3DPRIM_LINELIST_ADJ,
241 [PIPE_PRIM_LINE_STRIP_ADJACENCY] = GEN6_3DPRIM_LINESTRIP_ADJ,
242 [PIPE_PRIM_TRIANGLES_ADJACENCY] = GEN6_3DPRIM_TRILIST_ADJ,
243 [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = GEN6_3DPRIM_TRISTRIP_ADJ,
244 [ILO_PRIM_RECTANGLES] = GEN6_3DPRIM_RECTLIST,
245 };
246
247 assert(prim_mapping[prim]);
248
249 return prim_mapping[prim];
250 }
251
252 static inline void
253 gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder,
254 enum gen_3dprim_type topology)
255 {
256 const uint8_t cmd_len = 2;
257 uint32_t *dw;
258
259 ILO_DEV_ASSERT(builder->dev, 8, 8);
260
261 ilo_builder_batch_pointer(builder, cmd_len, &dw);
262
263 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
264 dw[1] = topology << GEN8_TOPOLOGY_DW1_TYPE__SHIFT;
265 }
266
267 static inline void
268 gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
269 int vb_index, uint32_t step_rate)
270 {
271 const uint8_t cmd_len = 3;
272 uint32_t *dw;
273
274 ILO_DEV_ASSERT(builder->dev, 8, 8);
275
276 ilo_builder_batch_pointer(builder, cmd_len, &dw);
277
278 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
279 dw[1] = vb_index;
280 if (step_rate)
281 dw[1] |= GEN8_INSTANCING_DW1_ENABLE;
282 dw[2] = step_rate;
283 }
284
285 static inline void
286 gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
287 const struct ilo_state_vf *vf)
288 {
289 const uint8_t cmd_len = 2;
290 uint32_t *dw;
291
292 ILO_DEV_ASSERT(builder->dev, 8, 8);
293
294 ilo_builder_batch_pointer(builder, cmd_len, &dw);
295
296 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
297 /* see vf_params_set_gen8_3DSTATE_VF_SGVS() */
298 dw[1] = vf->sgvs[0];
299 }
300
301 static inline void
302 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
303 const struct ilo_vb_state *vb,
304 const unsigned *vb_mapping,
305 const unsigned *instance_divisors,
306 unsigned vb_count)
307 {
308 uint8_t cmd_len;
309 uint32_t *dw;
310 unsigned pos, hw_idx;
311
312 ILO_DEV_ASSERT(builder->dev, 6, 8);
313
314 /*
315 * From the Sandy Bridge PRM, volume 2 part 1, page 82:
316 *
317 * "From 1 to 33 VBs can be specified..."
318 */
319 assert(vb_count <= 33);
320
321 if (!vb_count)
322 return;
323
324 cmd_len = 1 + 4 * vb_count;
325 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
326
327 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
328 dw++;
329 pos++;
330
331 for (hw_idx = 0; hw_idx < vb_count; hw_idx++) {
332 const unsigned instance_divisor = instance_divisors[hw_idx];
333 const unsigned pipe_idx = vb_mapping[hw_idx];
334 const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
335
336 dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
337
338 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
339 dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
340 else
341 dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
342
343 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
344 dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
345
346 if (instance_divisor)
347 dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA;
348 else
349 dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA;
350
351 /* use null vb if there is no buffer or the stride is out of range */
352 if (!cso->buffer || cso->stride > 2048) {
353 dw[0] |= GEN6_VB_DW0_IS_NULL;
354 dw[1] = 0;
355 dw[2] = 0;
356 dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ?
357 0 : instance_divisor;
358
359 continue;
360 }
361
362 dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
363
364 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
365 const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
366 const uint32_t start_offset = cso->buffer_offset;
367
368 ilo_builder_batch_reloc64(builder, pos + 1,
369 buf->bo, start_offset, 0);
370 dw[3] = buf->bo_size;
371 } else {
372 const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
373 const uint32_t start_offset = cso->buffer_offset;
374 const uint32_t end_offset = buf->bo_size - 1;
375
376 dw[3] = instance_divisor;
377
378 ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
379 ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
380 }
381
382 dw += 4;
383 pos += 4;
384 }
385 }
386
387 /* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
388 static inline void
389 gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
390 uint32_t vb_begin, uint32_t vb_end,
391 uint32_t stride)
392 {
393 const struct ilo_builder_writer *bat =
394 &builder->writers[ILO_BUILDER_WRITER_BATCH];
395 const uint8_t cmd_len = 1 + 4;
396 uint32_t *dw;
397 unsigned pos;
398
399 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
400
401 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
402
403 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
404 dw++;
405 pos++;
406
407 /* VERTEX_BUFFER_STATE */
408 dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
409 GEN6_VB_DW0_ACCESS_VERTEXDATA |
410 stride << GEN6_VB_DW0_PITCH__SHIFT;
411 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
412 dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
413
414 dw[3] = 0;
415
416 ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
417 ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
418 }
419
420 static inline void
421 gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
422 const struct ilo_state_vf *vf)
423 {
424 uint8_t cmd_len;
425 uint32_t *dw;
426
427 ILO_DEV_ASSERT(builder->dev, 6, 8);
428
429 cmd_len = 1 + 2 * (vf->internal_ve_count + vf->user_ve_count);
430
431 ilo_builder_batch_pointer(builder, cmd_len, &dw);
432
433 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
434 dw++;
435
436 /* see vf_set_gen6_3DSTATE_VERTEX_ELEMENTS() */
437 if (vf->internal_ve_count) {
438 memcpy(dw, vf->internal_ve,
439 sizeof(vf->internal_ve[0]) * vf->internal_ve_count);
440 dw += 2 * vf->internal_ve_count;
441 }
442 memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count);
443 }
444
445 static inline void
446 gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
447 const struct ilo_ib_state *ib,
448 bool enable_cut_index)
449 {
450 const uint8_t cmd_len = 3;
451 struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
452 uint32_t start_offset, end_offset;
453 int format;
454 uint32_t *dw;
455 unsigned pos;
456
457 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
458
459 if (!buf)
460 return;
461
462 /* this is moved to the new 3DSTATE_VF */
463 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5))
464 assert(!enable_cut_index);
465
466 switch (ib->hw_index_size) {
467 case 4:
468 format = GEN6_IB_DW0_FORMAT_DWORD;
469 break;
470 case 2:
471 format = GEN6_IB_DW0_FORMAT_WORD;
472 break;
473 case 1:
474 format = GEN6_IB_DW0_FORMAT_BYTE;
475 break;
476 default:
477 assert(!"unknown index size");
478 format = GEN6_IB_DW0_FORMAT_BYTE;
479 break;
480 }
481
482 /*
483 * set start_offset to 0 here and adjust pipe_draw_info::start with
484 * ib->draw_start_offset in 3DPRIMITIVE
485 */
486 start_offset = 0;
487 end_offset = buf->bo_size;
488
489 /* end_offset must also be aligned and is inclusive */
490 end_offset -= (end_offset % ib->hw_index_size);
491 end_offset--;
492
493 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
494
495 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
496 builder->mocs << GEN6_IB_DW0_MOCS__SHIFT |
497 format;
498 if (enable_cut_index)
499 dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
500
501 ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
502 ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
503 }
504
505 static inline void
506 gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
507 const struct ilo_ib_state *ib)
508 {
509 const uint8_t cmd_len = 5;
510 struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
511 int format;
512 uint32_t *dw;
513 unsigned pos;
514
515 ILO_DEV_ASSERT(builder->dev, 8, 8);
516
517 if (!buf)
518 return;
519
520 switch (ib->hw_index_size) {
521 case 4:
522 format = GEN8_IB_DW1_FORMAT_DWORD;
523 break;
524 case 2:
525 format = GEN8_IB_DW1_FORMAT_WORD;
526 break;
527 case 1:
528 format = GEN8_IB_DW1_FORMAT_BYTE;
529 break;
530 default:
531 assert(!"unknown index size");
532 format = GEN8_IB_DW1_FORMAT_BYTE;
533 break;
534 }
535
536 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
537
538 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
539 dw[1] = format |
540 builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
541 dw[4] = buf->bo_size;
542
543 /* ignore ib->offset here in favor of adjusting 3DPRIMITIVE */
544 ilo_builder_batch_reloc64(builder, pos + 2, buf->bo, 0, 0);
545 }
546
547 static inline void
548 gen6_3DSTATE_VS(struct ilo_builder *builder,
549 const struct ilo_state_vs *vs,
550 uint32_t kernel_offset)
551 {
552 const uint8_t cmd_len = 6;
553 uint32_t *dw;
554
555 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
556
557 ilo_builder_batch_pointer(builder, cmd_len, &dw);
558
559 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
560 dw[1] = kernel_offset;
561 /* see vs_set_gen6_3DSTATE_VS() */
562 dw[2] = vs->vs[0];
563 dw[3] = vs->vs[1];
564 dw[4] = vs->vs[2];
565 dw[5] = vs->vs[3];
566 }
567
568 static inline void
569 gen8_3DSTATE_VS(struct ilo_builder *builder,
570 const struct ilo_state_vs *vs,
571 uint32_t kernel_offset)
572 {
573 const uint8_t cmd_len = 9;
574 uint32_t *dw;
575
576 ILO_DEV_ASSERT(builder->dev, 8, 8);
577
578 ilo_builder_batch_pointer(builder, cmd_len, &dw);
579
580 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
581 dw[1] = kernel_offset;
582 dw[2] = 0;
583 /* see vs_set_gen6_3DSTATE_VS() */
584 dw[3] = vs->vs[0];
585 dw[4] = vs->vs[1];
586 dw[5] = 0;
587 dw[6] = vs->vs[2];
588 dw[7] = vs->vs[3];
589 dw[8] = vs->vs[4];
590 }
591
592 static inline void
593 gen7_3DSTATE_HS(struct ilo_builder *builder,
594 const struct ilo_state_hs *hs,
595 uint32_t kernel_offset)
596 {
597 const uint8_t cmd_len = 7;
598 uint32_t *dw;
599
600 ILO_DEV_ASSERT(builder->dev, 7, 7.5);
601
602 ilo_builder_batch_pointer(builder, cmd_len, &dw);
603
604 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
605 /* see hs_set_gen7_3DSTATE_HS() */
606 dw[1] = hs->hs[0];
607 dw[2] = hs->hs[1];
608 dw[3] = kernel_offset;
609 dw[4] = hs->hs[2];
610 dw[5] = hs->hs[3];
611 dw[6] = 0;
612 }
613
614 static inline void
615 gen8_3DSTATE_HS(struct ilo_builder *builder,
616 const struct ilo_state_hs *hs,
617 uint32_t kernel_offset)
618 {
619 const uint8_t cmd_len = 9;
620 uint32_t *dw;
621
622 ILO_DEV_ASSERT(builder->dev, 8, 8);
623
624 ilo_builder_batch_pointer(builder, cmd_len, &dw);
625
626 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
627 /* see hs_set_gen7_3DSTATE_HS() */
628 dw[1] = hs->hs[0];
629 dw[2] = hs->hs[1];
630 dw[3] = kernel_offset;
631 dw[4] = 0;
632 dw[5] = hs->hs[2];
633 dw[6] = 0;
634 dw[7] = hs->hs[3];
635 dw[8] = 0;
636 }
637
638 static inline void
639 gen7_3DSTATE_TE(struct ilo_builder *builder,
640 const struct ilo_state_ds *ds)
641 {
642 const uint8_t cmd_len = 4;
643 uint32_t *dw;
644
645 ILO_DEV_ASSERT(builder->dev, 7, 8);
646
647 ilo_builder_batch_pointer(builder, cmd_len, &dw);
648
649 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
650 /* see ds_set_gen7_3DSTATE_TE() */
651 dw[1] = ds->te[0];
652 dw[2] = ds->te[1];
653 dw[3] = ds->te[2];
654 }
655
656 static inline void
657 gen7_3DSTATE_DS(struct ilo_builder *builder,
658 const struct ilo_state_ds *ds,
659 uint32_t kernel_offset)
660 {
661 const uint8_t cmd_len = 6;
662 uint32_t *dw;
663
664 ILO_DEV_ASSERT(builder->dev, 7, 7.5);
665
666 ilo_builder_batch_pointer(builder, cmd_len, &dw);
667
668 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
669 /* see ds_set_gen7_3DSTATE_DS() */
670 dw[1] = kernel_offset;
671 dw[2] = ds->ds[0];
672 dw[3] = ds->ds[1];
673 dw[4] = ds->ds[2];
674 dw[5] = ds->ds[3];
675 }
676
677 static inline void
678 gen8_3DSTATE_DS(struct ilo_builder *builder,
679 const struct ilo_state_ds *ds,
680 uint32_t kernel_offset)
681 {
682 const uint8_t cmd_len = 9;
683 uint32_t *dw;
684
685 ILO_DEV_ASSERT(builder->dev, 8, 8);
686
687 ilo_builder_batch_pointer(builder, cmd_len, &dw);
688
689 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
690 /* see ds_set_gen7_3DSTATE_DS() */
691 dw[1] = kernel_offset;
692 dw[2] = 0;
693 dw[3] = ds->ds[0];
694 dw[4] = ds->ds[1];
695 dw[5] = 0;
696 dw[6] = ds->ds[2];
697 dw[7] = ds->ds[3];
698 dw[8] = ds->ds[4];
699 }
700
701 static inline void
702 gen6_3DSTATE_GS(struct ilo_builder *builder,
703 const struct ilo_state_gs *gs,
704 uint32_t kernel_offset)
705 {
706 const uint8_t cmd_len = 7;
707 uint32_t *dw;
708
709 ILO_DEV_ASSERT(builder->dev, 6, 6);
710
711 ilo_builder_batch_pointer(builder, cmd_len, &dw);
712
713 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
714 dw[1] = kernel_offset;
715 /* see gs_set_gen6_3DSTATE_GS() */
716 dw[2] = gs->gs[0];
717 dw[3] = gs->gs[1];
718 dw[4] = gs->gs[2];
719 dw[5] = gs->gs[3];
720 dw[6] = gs->gs[4];
721 }
722
723 static inline void
724 gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
725 int index, unsigned svbi,
726 unsigned max_svbi,
727 bool load_vertex_count)
728 {
729 const uint8_t cmd_len = 4;
730 uint32_t *dw;
731
732 ILO_DEV_ASSERT(builder->dev, 6, 6);
733 assert(index >= 0 && index < 4);
734
735 ilo_builder_batch_pointer(builder, cmd_len, &dw);
736
737 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
738
739 dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
740 if (load_vertex_count)
741 dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
742
743 dw[2] = svbi;
744 dw[3] = max_svbi;
745 }
746
747 static inline void
748 gen7_3DSTATE_GS(struct ilo_builder *builder,
749 const struct ilo_state_gs *gs,
750 uint32_t kernel_offset)
751 {
752 const uint8_t cmd_len = 7;
753 uint32_t *dw;
754
755 ILO_DEV_ASSERT(builder->dev, 7, 7.5);
756
757 ilo_builder_batch_pointer(builder, cmd_len, &dw);
758
759 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
760 dw[1] = kernel_offset;
761 /* see gs_set_gen7_3DSTATE_GS() */
762 dw[2] = gs->gs[0];
763 dw[3] = gs->gs[1];
764 dw[4] = gs->gs[2];
765 dw[5] = gs->gs[3];
766 dw[6] = 0;
767 }
768
769 static inline void
770 gen8_3DSTATE_GS(struct ilo_builder *builder,
771 const struct ilo_state_gs *gs,
772 uint32_t kernel_offset)
773 {
774 const uint8_t cmd_len = 10;
775 uint32_t *dw;
776
777 ILO_DEV_ASSERT(builder->dev, 8, 8);
778
779 ilo_builder_batch_pointer(builder, cmd_len, &dw);
780
781 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
782 dw[1] = kernel_offset;
783 dw[2] = 0;
784 /* see gs_set_gen7_3DSTATE_GS() */
785 dw[3] = gs->gs[0];
786 dw[4] = gs->gs[1];
787 dw[5] = 0;
788 dw[6] = gs->gs[2];
789 dw[7] = gs->gs[3];
790 dw[8] = 0;
791 dw[9] = gs->gs[4];
792 }
793
794 static inline void
795 gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
796 const struct ilo_state_sol *sol)
797 {
798 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
799 uint32_t *dw;
800
801 ILO_DEV_ASSERT(builder->dev, 7, 8);
802
803 ilo_builder_batch_pointer(builder, cmd_len, &dw);
804
805 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
806 /* see sol_set_gen7_3DSTATE_STREAMOUT() */
807 dw[1] = sol->so[0];
808 dw[2] = sol->so[1];
809 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
810 dw[3] = sol->so[2];
811 dw[4] = sol->so[3];
812 }
813 }
814
815 static inline void
816 gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
817 const struct ilo_state_sol *sol)
818 {
819 /*
820 * Note that "DWord Length" has 9 bits for this command and the type of
821 * cmd_len cannot be uint8_t.
822 */
823 uint16_t cmd_len;
824 int cmd_decl_count;
825 uint32_t *dw;
826
827 ILO_DEV_ASSERT(builder->dev, 7, 8);
828
829 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
830 cmd_decl_count = sol->decl_count;
831 } else {
832 /*
833 * From the Ivy Bridge PRM, volume 2 part 1, page 201:
834 *
835 * "Errata: All 128 decls for all four streams must be included
836 * whenever this command is issued. The "Num Entries [n]" fields
837 * still contain the actual numbers of valid decls."
838 */
839 cmd_decl_count = 128;
840 }
841
842 cmd_len = 3 + 2 * cmd_decl_count;
843
844 ilo_builder_batch_pointer(builder, cmd_len, &dw);
845
846 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
847 /* see sol_set_gen7_3DSTATE_SO_DECL_LIST() */
848 dw[1] = sol->so[4];
849 dw[2] = sol->so[5];
850 memcpy(&dw[3], sol->decl, sizeof(sol->decl[0]) * sol->decl_count);
851
852 if (sol->decl_count < cmd_decl_count) {
853 memset(&dw[3 + 2 * sol->decl_count], 0, sizeof(sol->decl[0]) *
854 cmd_decl_count - sol->decl_count);
855 }
856 }
857
858 static inline void
859 gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
860 const struct pipe_stream_output_target *so_target)
861 {
862 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
863 struct ilo_buffer *buf;
864 int start, end;
865 uint32_t *dw;
866 unsigned pos;
867
868 ILO_DEV_ASSERT(builder->dev, 7, 8);
869
870 buf = ilo_buffer(so_target->buffer);
871
872 /* DWord-aligned */
873 assert(stride % 4 == 0);
874 assert(so_target->buffer_offset % 4 == 0);
875
876 stride &= ~3;
877 start = so_target->buffer_offset & ~3;
878 end = (start + so_target->buffer_size) & ~3;
879
880 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
881
882 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
883 dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
884 stride;
885
886 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
887 dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
888
889 dw[4] = end - start;
890 dw[5] = 0;
891 dw[6] = 0;
892 dw[7] = 0;
893
894 ilo_builder_batch_reloc64(builder, pos + 2,
895 buf->bo, start, INTEL_RELOC_WRITE);
896 } else {
897 dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
898
899 ilo_builder_batch_reloc(builder, pos + 2,
900 buf->bo, start, INTEL_RELOC_WRITE);
901 ilo_builder_batch_reloc(builder, pos + 3,
902 buf->bo, end, INTEL_RELOC_WRITE);
903 }
904 }
905
906 static inline void
907 gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
908 {
909 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
910 uint32_t *dw;
911
912 ILO_DEV_ASSERT(builder->dev, 7, 8);
913
914 ilo_builder_batch_pointer(builder, cmd_len, &dw);
915
916 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
917 dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
918 dw[2] = 0;
919 dw[3] = 0;
920
921 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
922 dw[4] = 0;
923 dw[5] = 0;
924 dw[6] = 0;
925 dw[7] = 0;
926 }
927 }
928
929 static inline void
930 gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
931 uint32_t vs_binding_table,
932 uint32_t gs_binding_table,
933 uint32_t ps_binding_table)
934 {
935 const uint8_t cmd_len = 4;
936 uint32_t *dw;
937
938 ILO_DEV_ASSERT(builder->dev, 6, 6);
939
940 ilo_builder_batch_pointer(builder, cmd_len, &dw);
941
942 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
943 GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
944 GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
945 GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
946 (cmd_len - 2);
947 dw[1] = vs_binding_table;
948 dw[2] = gs_binding_table;
949 dw[3] = ps_binding_table;
950 }
951
952 static inline void
953 gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
954 uint32_t vs_sampler_state,
955 uint32_t gs_sampler_state,
956 uint32_t ps_sampler_state)
957 {
958 const uint8_t cmd_len = 4;
959 uint32_t *dw;
960
961 ILO_DEV_ASSERT(builder->dev, 6, 6);
962
963 ilo_builder_batch_pointer(builder, cmd_len, &dw);
964
965 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
966 GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
967 GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
968 GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
969 (cmd_len - 2);
970 dw[1] = vs_sampler_state;
971 dw[2] = gs_sampler_state;
972 dw[3] = ps_sampler_state;
973 }
974
975 static inline void
976 gen7_3dstate_pointer(struct ilo_builder *builder,
977 int subop, uint32_t pointer)
978 {
979 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
980 GEN6_RENDER_SUBTYPE_3D |
981 subop;
982 const uint8_t cmd_len = 2;
983 uint32_t *dw;
984
985 ILO_DEV_ASSERT(builder->dev, 7, 8);
986
987 ilo_builder_batch_pointer(builder, cmd_len, &dw);
988
989 dw[0] = cmd | (cmd_len - 2);
990 dw[1] = pointer;
991 }
992
993 static inline void
994 gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
995 uint32_t binding_table)
996 {
997 gen7_3dstate_pointer(builder,
998 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
999 binding_table);
1000 }
1001
1002 static inline void
1003 gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
1004 uint32_t binding_table)
1005 {
1006 gen7_3dstate_pointer(builder,
1007 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
1008 binding_table);
1009 }
1010
1011 static inline void
1012 gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
1013 uint32_t binding_table)
1014 {
1015 gen7_3dstate_pointer(builder,
1016 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
1017 binding_table);
1018 }
1019
1020 static inline void
1021 gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
1022 uint32_t binding_table)
1023 {
1024 gen7_3dstate_pointer(builder,
1025 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
1026 binding_table);
1027 }
1028
1029 static inline void
1030 gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
1031 uint32_t sampler_state)
1032 {
1033 gen7_3dstate_pointer(builder,
1034 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
1035 sampler_state);
1036 }
1037
1038 static inline void
1039 gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
1040 uint32_t sampler_state)
1041 {
1042 gen7_3dstate_pointer(builder,
1043 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
1044 sampler_state);
1045 }
1046
1047 static inline void
1048 gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
1049 uint32_t sampler_state)
1050 {
1051 gen7_3dstate_pointer(builder,
1052 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
1053 sampler_state);
1054 }
1055
1056 static inline void
1057 gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
1058 uint32_t sampler_state)
1059 {
1060 gen7_3dstate_pointer(builder,
1061 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
1062 sampler_state);
1063 }
1064
1065 static inline void
1066 gen6_3dstate_constant(struct ilo_builder *builder, int subop,
1067 const uint32_t *bufs, const int *sizes,
1068 int num_bufs)
1069 {
1070 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1071 GEN6_RENDER_SUBTYPE_3D |
1072 subop;
1073 const uint8_t cmd_len = 5;
1074 unsigned buf_enabled = 0x0;
1075 uint32_t buf_dw[4], *dw;
1076 int max_read_length, total_read_length;
1077 int i;
1078
1079 ILO_DEV_ASSERT(builder->dev, 6, 6);
1080
1081 assert(num_bufs <= 4);
1082
1083 /*
1084 * From the Sandy Bridge PRM, volume 2 part 1, page 138:
1085 *
1086 * "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
1087 * incremented to represent the actual read length) must be less than
1088 * or equal to 32"
1089 *
1090 * From the Sandy Bridge PRM, volume 2 part 1, page 161:
1091 *
1092 * "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
1093 * incremented to represent the actual read length) must be less than
1094 * or equal to 64"
1095 *
1096 * From the Sandy Bridge PRM, volume 2 part 1, page 287:
1097 *
1098 * "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
1099 * incremented to represent the actual read length) must be less than
1100 * or equal to 64"
1101 */
1102 switch (subop) {
1103 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
1104 max_read_length = 32;
1105 break;
1106 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
1107 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
1108 max_read_length = 64;
1109 break;
1110 default:
1111 assert(!"unknown pcb subop");
1112 max_read_length = 0;
1113 break;
1114 }
1115
1116 total_read_length = 0;
1117 for (i = 0; i < 4; i++) {
1118 if (i < num_bufs && sizes[i]) {
1119 /* in 256-bit units */
1120 const int read_len = (sizes[i] + 31) / 32;
1121
1122 assert(bufs[i] % 32 == 0);
1123 assert(read_len <= 32);
1124
1125 buf_enabled |= 1 << i;
1126 buf_dw[i] = bufs[i] | (read_len - 1);
1127
1128 total_read_length += read_len;
1129 } else {
1130 buf_dw[i] = 0;
1131 }
1132 }
1133
1134 assert(total_read_length <= max_read_length);
1135
1136 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1137
1138 dw[0] = cmd | (cmd_len - 2) |
1139 buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
1140 builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
1141
1142 memcpy(&dw[1], buf_dw, sizeof(buf_dw));
1143 }
1144
1145 static inline void
1146 gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1147 const uint32_t *bufs, const int *sizes,
1148 int num_bufs)
1149 {
1150 gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1151 bufs, sizes, num_bufs);
1152 }
1153
1154 static inline void
1155 gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1156 const uint32_t *bufs, const int *sizes,
1157 int num_bufs)
1158 {
1159 gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1160 bufs, sizes, num_bufs);
1161 }
1162
1163 static inline void
1164 gen7_3dstate_constant(struct ilo_builder *builder,
1165 int subop,
1166 const uint32_t *bufs, const int *sizes,
1167 int num_bufs)
1168 {
1169 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1170 GEN6_RENDER_SUBTYPE_3D |
1171 subop;
1172 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
1173 uint32_t payload[6], *dw;
1174 int total_read_length, i;
1175
1176 ILO_DEV_ASSERT(builder->dev, 7, 8);
1177
1178 /* VS, HS, DS, GS, and PS variants */
1179 assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
1180 subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
1181 subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
1182
1183 assert(num_bufs <= 4);
1184
1185 payload[0] = 0;
1186 payload[1] = 0;
1187
1188 total_read_length = 0;
1189 for (i = 0; i < 4; i++) {
1190 int read_len;
1191
1192 /*
1193 * From the Ivy Bridge PRM, volume 2 part 1, page 112:
1194 *
1195 * "Constant buffers must be enabled in order from Constant Buffer 0
1196 * to Constant Buffer 3 within this command. For example, it is
1197 * not allowed to enable Constant Buffer 1 by programming a
1198 * non-zero value in the VS Constant Buffer 1 Read Length without a
1199 * non-zero value in VS Constant Buffer 0 Read Length."
1200 */
1201 if (i >= num_bufs || !sizes[i]) {
1202 for (; i < 4; i++) {
1203 assert(i >= num_bufs || !sizes[i]);
1204 payload[2 + i] = 0;
1205 }
1206 break;
1207 }
1208
1209 /* read lengths are in 256-bit units */
1210 read_len = (sizes[i] + 31) / 32;
1211 /* the lower 5 bits are used for memory object control state */
1212 assert(bufs[i] % 32 == 0);
1213
1214 payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
1215 payload[2 + i] = bufs[i];
1216
1217 total_read_length += read_len;
1218 }
1219
1220 /*
1221 * From the Ivy Bridge PRM, volume 2 part 1, page 113:
1222 *
1223 * "The sum of all four read length fields must be less than or equal
1224 * to the size of 64"
1225 */
1226 assert(total_read_length <= 64);
1227
1228 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1229
1230 dw[0] = cmd | (cmd_len - 2);
1231 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1232 dw[1] = payload[0];
1233 dw[2] = payload[1];
1234 dw[3] = payload[2];
1235 dw[4] = 0;
1236 dw[5] = payload[3];
1237 dw[6] = 0;
1238 dw[7] = payload[4];
1239 dw[8] = 0;
1240 dw[9] = payload[5];
1241 dw[10] = 0;
1242 } else {
1243 payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
1244
1245 memcpy(&dw[1], payload, sizeof(payload));
1246 }
1247 }
1248
1249 static inline void
1250 gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1251 const uint32_t *bufs, const int *sizes,
1252 int num_bufs)
1253 {
1254 gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1255 bufs, sizes, num_bufs);
1256 }
1257
1258 static inline void
1259 gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
1260 const uint32_t *bufs, const int *sizes,
1261 int num_bufs)
1262 {
1263 gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
1264 bufs, sizes, num_bufs);
1265 }
1266
1267 static inline void
1268 gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
1269 const uint32_t *bufs, const int *sizes,
1270 int num_bufs)
1271 {
1272 gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
1273 bufs, sizes, num_bufs);
1274 }
1275
1276 static inline void
1277 gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1278 const uint32_t *bufs, const int *sizes,
1279 int num_bufs)
1280 {
1281 gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1282 bufs, sizes, num_bufs);
1283 }
1284
1285 static inline uint32_t
1286 gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
1287 const uint32_t *surface_states,
1288 int num_surface_states)
1289 {
1290 const int state_align = 32;
1291 const int state_len = num_surface_states;
1292 uint32_t state_offset, *dw;
1293
1294 ILO_DEV_ASSERT(builder->dev, 6, 8);
1295
1296 /*
1297 * From the Sandy Bridge PRM, volume 4 part 1, page 69:
1298 *
1299 * "It is stored as an array of up to 256 elements..."
1300 */
1301 assert(num_surface_states <= 256);
1302
1303 if (!num_surface_states)
1304 return 0;
1305
1306 state_offset = ilo_builder_surface_pointer(builder,
1307 ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
1308 memcpy(dw, surface_states, state_len << 2);
1309
1310 return state_offset;
1311 }
1312
1313 static inline uint32_t
1314 gen6_SURFACE_STATE(struct ilo_builder *builder,
1315 const struct ilo_state_surface *surf)
1316 {
1317 int state_align, state_len;
1318 uint32_t state_offset, *dw;
1319
1320 ILO_DEV_ASSERT(builder->dev, 6, 8);
1321
1322 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1323 state_align = 64;
1324 state_len = 13;
1325
1326 state_offset = ilo_builder_surface_pointer(builder,
1327 ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
1328 memcpy(dw, surf->surface, state_len << 2);
1329
1330 if (surf->bo) {
1331 const uint32_t mocs = (surf->scanout) ?
1332 (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
1333
1334 dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
1335
1336 ilo_builder_surface_reloc64(builder, state_offset, 8, surf->bo,
1337 surf->surface[8], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
1338 }
1339 } else {
1340 state_align = 32;
1341 state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 8 : 6;
1342
1343 state_offset = ilo_builder_surface_pointer(builder,
1344 ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
1345 memcpy(dw, surf->surface, state_len << 2);
1346
1347 if (surf->bo) {
1348 /*
1349 * For scanouts, we should not enable caching in LLC. Since we only
1350 * enable that on Gen8+, we are fine here.
1351 */
1352 dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
1353
1354 ilo_builder_surface_reloc(builder, state_offset, 1, surf->bo,
1355 surf->surface[1], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
1356 }
1357 }
1358
1359 return state_offset;
1360 }
1361
1362 static inline uint32_t
1363 gen6_so_SURFACE_STATE(struct ilo_builder *builder,
1364 const struct pipe_stream_output_target *so,
1365 const struct pipe_stream_output_info *so_info,
1366 int so_index)
1367 {
1368 struct ilo_buffer *buf = ilo_buffer(so->buffer);
1369 struct ilo_state_surface_buffer_info info;
1370 struct ilo_state_surface surf;
1371
1372 ILO_DEV_ASSERT(builder->dev, 6, 6);
1373
1374 memset(&info, 0, sizeof(info));
1375 info.buf = buf;
1376 info.access = ILO_STATE_SURFACE_ACCESS_DP_SVB;
1377
1378 switch (so_info->output[so_index].num_components) {
1379 case 1:
1380 info.format = GEN6_FORMAT_R32_FLOAT;
1381 info.format_size = 4;
1382 break;
1383 case 2:
1384 info.format = GEN6_FORMAT_R32G32_FLOAT;
1385 info.format_size = 8;
1386 break;
1387 case 3:
1388 info.format = GEN6_FORMAT_R32G32B32_FLOAT;
1389 info.format_size = 12;
1390 break;
1391 case 4:
1392 info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
1393 info.format_size = 16;
1394 break;
1395 default:
1396 assert(!"unexpected SO components length");
1397 info.format = GEN6_FORMAT_R32_FLOAT;
1398 info.format_size = 4;
1399 break;
1400 }
1401
1402 info.struct_size =
1403 so_info->stride[so_info->output[so_index].output_buffer] * 4;
1404 info.offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
1405 info.size = so->buffer_size - so_info->output[so_index].dst_offset * 4;
1406
1407 memset(&surf, 0, sizeof(surf));
1408 ilo_state_surface_init_for_buffer(&surf, builder->dev, &info);
1409 surf.bo = info.buf->bo;
1410
1411 return gen6_SURFACE_STATE(builder, &surf);
1412 }
1413
1414 static inline uint32_t
1415 gen6_SAMPLER_STATE(struct ilo_builder *builder,
1416 const struct ilo_state_sampler *samplers,
1417 const uint32_t *sampler_border_colors,
1418 int sampler_count)
1419 {
1420 const int state_align = 32;
1421 const int state_len = 4 * sampler_count;
1422 uint32_t state_offset, *dw;
1423 int i;
1424
1425 ILO_DEV_ASSERT(builder->dev, 6, 8);
1426
1427 /*
1428 * From the Sandy Bridge PRM, volume 4 part 1, page 101:
1429 *
1430 * "The sampler state is stored as an array of up to 16 elements..."
1431 */
1432 assert(sampler_count <= 16);
1433
1434 if (!sampler_count)
1435 return 0;
1436
1437 /*
1438 * From the Sandy Bridge PRM, volume 2 part 1, page 132:
1439 *
1440 * "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
1441 * multiples of 4) the vertex shader 0 kernel uses. Used only for
1442 * prefetching the associated sampler state entries.
1443 *
1444 * It also applies to other shader stages.
1445 */
1446 ilo_builder_dynamic_pad_top(builder, 4 * (4 - (sampler_count % 4)));
1447
1448 state_offset = ilo_builder_dynamic_pointer(builder,
1449 ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
1450
1451 for (i = 0; i < sampler_count; i++) {
1452 /* see sampler_set_gen6_SAMPLER_STATE() */
1453 dw[0] = samplers[i].sampler[0];
1454 dw[1] = samplers[i].sampler[1];
1455 dw[3] = samplers[i].sampler[2];
1456
1457 assert(!(sampler_border_colors[i] & 0x1f));
1458 dw[2] = sampler_border_colors[i];
1459
1460 dw += 4;
1461 }
1462
1463 return state_offset;
1464 }
1465
1466 static inline uint32_t
1467 gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
1468 const struct ilo_state_sampler_border *border)
1469 {
1470 const int state_align =
1471 (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
1472 const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
1473
1474 ILO_DEV_ASSERT(builder->dev, 6, 8);
1475
1476 /*
1477 * see border_set_gen6_SAMPLER_BORDER_COLOR_STATE() and
1478 * border_set_gen7_SAMPLER_BORDER_COLOR_STATE()
1479 */
1480 return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1481 state_align, state_len, border->color);
1482 }
1483
1484 static inline uint32_t
1485 gen6_push_constant_buffer(struct ilo_builder *builder,
1486 int size, void **pcb)
1487 {
1488 /*
1489 * For all VS, GS, FS, and CS push constant buffers, they must be aligned
1490 * to 32 bytes, and their sizes are specified in 256-bit units.
1491 */
1492 const int state_align = 32;
1493 const int state_len = align(size, 32) / 4;
1494 uint32_t state_offset;
1495 char *buf;
1496
1497 ILO_DEV_ASSERT(builder->dev, 6, 8);
1498
1499 state_offset = ilo_builder_dynamic_pointer(builder,
1500 ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
1501
1502 /* zero out the unused range */
1503 if (size < state_len * 4)
1504 memset(&buf[size], 0, state_len * 4 - size);
1505
1506 if (pcb)
1507 *pcb = buf;
1508
1509 return state_offset;
1510 }
1511
1512 static inline uint32_t
1513 gen6_user_vertex_buffer(struct ilo_builder *builder,
1514 int size, const void *vertices)
1515 {
1516 const int state_align = 8;
1517 const int state_len = size / 4;
1518
1519 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
1520
1521 assert(size % 4 == 0);
1522
1523 return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1524 state_align, state_len, vertices);
1525 }
1526
1527 #endif /* ILO_BUILDER_3D_TOP_H */