ilo: replace ilo_view_surface with ilo_state_surface
[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_shader.h"
34 #include "intel_winsys.h"
35
36 #include "ilo_core.h"
37 #include "ilo_dev.h"
38 #include "ilo_state_3d.h"
39 #include "ilo_builder.h"
40
41 static inline void
42 gen6_3DSTATE_URB(struct ilo_builder *builder,
43 int vs_total_size, int gs_total_size,
44 int vs_entry_size, int gs_entry_size)
45 {
46 const uint8_t cmd_len = 3;
47 const int row_size = 128; /* 1024 bits */
48 int vs_alloc_size, gs_alloc_size;
49 int vs_num_entries, gs_num_entries;
50 uint32_t *dw;
51
52 ILO_DEV_ASSERT(builder->dev, 6, 6);
53
54 /* in 1024-bit URB rows */
55 vs_alloc_size = (vs_entry_size + row_size - 1) / row_size;
56 gs_alloc_size = (gs_entry_size + row_size - 1) / row_size;
57
58 /* the valid range is [1, 5] */
59 if (!vs_alloc_size)
60 vs_alloc_size = 1;
61 if (!gs_alloc_size)
62 gs_alloc_size = 1;
63 assert(vs_alloc_size <= 5 && gs_alloc_size <= 5);
64
65 /* the valid range is [24, 256] in multiples of 4 */
66 vs_num_entries = (vs_total_size / row_size / vs_alloc_size) & ~3;
67 if (vs_num_entries > 256)
68 vs_num_entries = 256;
69 assert(vs_num_entries >= 24);
70
71 /* the valid range is [0, 256] in multiples of 4 */
72 gs_num_entries = (gs_total_size / row_size / gs_alloc_size) & ~3;
73 if (gs_num_entries > 256)
74 gs_num_entries = 256;
75
76 ilo_builder_batch_pointer(builder, cmd_len, &dw);
77
78 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_URB) | (cmd_len - 2);
79 dw[1] = (vs_alloc_size - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
80 vs_num_entries << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
81 dw[2] = gs_num_entries << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
82 (gs_alloc_size - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
83 }
84
85 static inline void
86 gen7_3dstate_push_constant_alloc(struct ilo_builder *builder,
87 int subop, int offset, int size)
88 {
89 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
90 GEN6_RENDER_SUBTYPE_3D |
91 subop;
92 const uint8_t cmd_len = 2;
93 const int slice_count = ((ilo_dev_gen(builder->dev) == ILO_GEN(7.5) &&
94 builder->dev->gt == 3) ||
95 ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 2 : 1;
96 uint32_t *dw;
97 int end;
98
99 ILO_DEV_ASSERT(builder->dev, 7, 8);
100
101 /* VS, HS, DS, GS, and PS variants */
102 assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS &&
103 subop <= GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS);
104
105 /*
106 * From the Ivy Bridge PRM, volume 2 part 1, page 68:
107 *
108 * "(A table that says the maximum size of each constant buffer is
109 * 16KB")
110 *
111 * From the Ivy Bridge PRM, volume 2 part 1, page 115:
112 *
113 * "The sum of the Constant Buffer Offset and the Constant Buffer Size
114 * may not exceed the maximum value of the Constant Buffer Size."
115 *
116 * Thus, the valid range of buffer end is [0KB, 16KB].
117 */
118 end = (offset + size) / 1024;
119 if (end > 16 * slice_count) {
120 assert(!"invalid constant buffer end");
121 end = 16 * slice_count;
122 }
123
124 /* the valid range of buffer offset is [0KB, 15KB] */
125 offset = (offset + 1023) / 1024;
126 if (offset > 15 * slice_count) {
127 assert(!"invalid constant buffer offset");
128 offset = 15 * slice_count;
129 }
130
131 if (offset > end) {
132 assert(!size);
133 offset = end;
134 }
135
136 /* the valid range of buffer size is [0KB, 15KB] */
137 size = end - offset;
138 if (size > 15 * slice_count) {
139 assert(!"invalid constant buffer size");
140 size = 15 * slice_count;
141 }
142
143 assert(offset % slice_count == 0 && size % slice_count == 0);
144
145 ilo_builder_batch_pointer(builder, cmd_len, &dw);
146
147 dw[0] = cmd | (cmd_len - 2);
148 dw[1] = offset << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
149 size;
150 }
151
152 static inline void
153 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder *builder,
154 int offset, int size)
155 {
156 gen7_3dstate_push_constant_alloc(builder,
157 GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_VS, offset, size);
158 }
159
160 static inline void
161 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder *builder,
162 int offset, int size)
163 {
164 gen7_3dstate_push_constant_alloc(builder,
165 GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_HS, offset, size);
166 }
167
168 static inline void
169 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder *builder,
170 int offset, int size)
171 {
172 gen7_3dstate_push_constant_alloc(builder,
173 GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_DS, offset, size);
174 }
175
176 static inline void
177 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder *builder,
178 int offset, int size)
179 {
180 gen7_3dstate_push_constant_alloc(builder,
181 GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_GS, offset, size);
182 }
183
184 static inline void
185 gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder *builder,
186 int offset, int size)
187 {
188 gen7_3dstate_push_constant_alloc(builder,
189 GEN7_RENDER_OPCODE_3DSTATE_PUSH_CONSTANT_ALLOC_PS, offset, size);
190 }
191
192 static inline void
193 gen7_3dstate_urb(struct ilo_builder *builder,
194 int subop, int offset, int size,
195 int entry_size)
196 {
197 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
198 GEN6_RENDER_SUBTYPE_3D |
199 subop;
200 const uint8_t cmd_len = 2;
201 const int row_size = 64; /* 512 bits */
202 int alloc_size, num_entries, min_entries, max_entries;
203 uint32_t *dw;
204
205 ILO_DEV_ASSERT(builder->dev, 7, 8);
206
207 /* VS, HS, DS, and GS variants */
208 assert(subop >= GEN7_RENDER_OPCODE_3DSTATE_URB_VS &&
209 subop <= GEN7_RENDER_OPCODE_3DSTATE_URB_GS);
210
211 /* in multiples of 8KB */
212 assert(offset % 8192 == 0);
213 offset /= 8192;
214
215 /* in multiple of 512-bit rows */
216 alloc_size = (entry_size + row_size - 1) / row_size;
217 if (!alloc_size)
218 alloc_size = 1;
219
220 /*
221 * From the Ivy Bridge PRM, volume 2 part 1, page 34:
222 *
223 * "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
224 * cause performance to decrease due to banking in the URB. Element
225 * sizes of 16 to 20 should be programmed with six 512-bit URB rows."
226 */
227 if (subop == GEN7_RENDER_OPCODE_3DSTATE_URB_VS && alloc_size == 5)
228 alloc_size = 6;
229
230 /* in multiples of 8 */
231 num_entries = (size / row_size / alloc_size) & ~7;
232
233 switch (subop) {
234 case GEN7_RENDER_OPCODE_3DSTATE_URB_VS:
235 switch (ilo_dev_gen(builder->dev)) {
236 case ILO_GEN(8):
237 max_entries = 2560;
238 min_entries = 64;
239 break;
240 case ILO_GEN(7.5):
241 max_entries = (builder->dev->gt >= 2) ? 1664 : 640;
242 min_entries = (builder->dev->gt >= 2) ? 64 : 32;
243 break;
244 case ILO_GEN(7):
245 default:
246 max_entries = (builder->dev->gt == 2) ? 704 : 512;
247 min_entries = 32;
248 break;
249 }
250
251 assert(num_entries >= min_entries);
252 if (num_entries > max_entries)
253 num_entries = max_entries;
254 break;
255 case GEN7_RENDER_OPCODE_3DSTATE_URB_HS:
256 max_entries = (builder->dev->gt == 2) ? 64 : 32;
257 if (num_entries > max_entries)
258 num_entries = max_entries;
259 break;
260 case GEN7_RENDER_OPCODE_3DSTATE_URB_DS:
261 if (num_entries)
262 assert(num_entries >= 138);
263 break;
264 case GEN7_RENDER_OPCODE_3DSTATE_URB_GS:
265 switch (ilo_dev_gen(builder->dev)) {
266 case ILO_GEN(8):
267 max_entries = 960;
268 break;
269 case ILO_GEN(7.5):
270 max_entries = (builder->dev->gt >= 2) ? 640 : 256;
271 break;
272 case ILO_GEN(7):
273 default:
274 max_entries = (builder->dev->gt == 2) ? 320 : 192;
275 break;
276 }
277
278 if (num_entries > max_entries)
279 num_entries = max_entries;
280 break;
281 default:
282 break;
283 }
284
285 ilo_builder_batch_pointer(builder, cmd_len, &dw);
286
287 dw[0] = cmd | (cmd_len - 2);
288 dw[1] = offset << GEN7_URB_DW1_OFFSET__SHIFT |
289 (alloc_size - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
290 num_entries;
291 }
292
293 static inline void
294 gen7_3DSTATE_URB_VS(struct ilo_builder *builder,
295 int offset, int size, int entry_size)
296 {
297 gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_VS,
298 offset, size, entry_size);
299 }
300
301 static inline void
302 gen7_3DSTATE_URB_HS(struct ilo_builder *builder,
303 int offset, int size, int entry_size)
304 {
305 gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_HS,
306 offset, size, entry_size);
307 }
308
309 static inline void
310 gen7_3DSTATE_URB_DS(struct ilo_builder *builder,
311 int offset, int size, int entry_size)
312 {
313 gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_DS,
314 offset, size, entry_size);
315 }
316
317 static inline void
318 gen7_3DSTATE_URB_GS(struct ilo_builder *builder,
319 int offset, int size, int entry_size)
320 {
321 gen7_3dstate_urb(builder, GEN7_RENDER_OPCODE_3DSTATE_URB_GS,
322 offset, size, entry_size);
323 }
324
325 static inline void
326 gen75_3DSTATE_VF(struct ilo_builder *builder,
327 bool enable_cut_index,
328 uint32_t cut_index)
329 {
330 const uint8_t cmd_len = 2;
331 uint32_t *dw;
332
333 ILO_DEV_ASSERT(builder->dev, 7.5, 8);
334
335 ilo_builder_batch_pointer(builder, cmd_len, &dw);
336
337 dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2);
338 if (enable_cut_index)
339 dw[0] |= GEN75_VF_DW0_CUT_INDEX_ENABLE;
340
341 dw[1] = cut_index;
342 }
343
344 static inline void
345 gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
346 bool enable)
347 {
348 const uint8_t cmd_len = 1;
349 const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
350 enable;
351
352 ILO_DEV_ASSERT(builder->dev, 6, 8);
353
354 ilo_builder_batch_write(builder, cmd_len, &dw0);
355 }
356
357 /**
358 * Translate a pipe primitive type to the matching hardware primitive type.
359 */
360 static inline int
361 gen6_3d_translate_pipe_prim(unsigned prim)
362 {
363 static const int prim_mapping[ILO_PRIM_MAX] = {
364 [PIPE_PRIM_POINTS] = GEN6_3DPRIM_POINTLIST,
365 [PIPE_PRIM_LINES] = GEN6_3DPRIM_LINELIST,
366 [PIPE_PRIM_LINE_LOOP] = GEN6_3DPRIM_LINELOOP,
367 [PIPE_PRIM_LINE_STRIP] = GEN6_3DPRIM_LINESTRIP,
368 [PIPE_PRIM_TRIANGLES] = GEN6_3DPRIM_TRILIST,
369 [PIPE_PRIM_TRIANGLE_STRIP] = GEN6_3DPRIM_TRISTRIP,
370 [PIPE_PRIM_TRIANGLE_FAN] = GEN6_3DPRIM_TRIFAN,
371 [PIPE_PRIM_QUADS] = GEN6_3DPRIM_QUADLIST,
372 [PIPE_PRIM_QUAD_STRIP] = GEN6_3DPRIM_QUADSTRIP,
373 [PIPE_PRIM_POLYGON] = GEN6_3DPRIM_POLYGON,
374 [PIPE_PRIM_LINES_ADJACENCY] = GEN6_3DPRIM_LINELIST_ADJ,
375 [PIPE_PRIM_LINE_STRIP_ADJACENCY] = GEN6_3DPRIM_LINESTRIP_ADJ,
376 [PIPE_PRIM_TRIANGLES_ADJACENCY] = GEN6_3DPRIM_TRILIST_ADJ,
377 [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = GEN6_3DPRIM_TRISTRIP_ADJ,
378 [ILO_PRIM_RECTANGLES] = GEN6_3DPRIM_RECTLIST,
379 };
380
381 assert(prim_mapping[prim]);
382
383 return prim_mapping[prim];
384 }
385
386 static inline void
387 gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder, unsigned pipe_prim)
388 {
389 const uint8_t cmd_len = 2;
390 const int prim = gen6_3d_translate_pipe_prim(pipe_prim);
391 uint32_t *dw;
392
393 ILO_DEV_ASSERT(builder->dev, 8, 8);
394
395 ilo_builder_batch_pointer(builder, cmd_len, &dw);
396
397 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
398 dw[1] = prim;
399 }
400
401 static inline void
402 gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
403 int vb_index, uint32_t step_rate)
404 {
405 const uint8_t cmd_len = 3;
406 uint32_t *dw;
407
408 ILO_DEV_ASSERT(builder->dev, 8, 8);
409
410 ilo_builder_batch_pointer(builder, cmd_len, &dw);
411
412 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
413 dw[1] = vb_index;
414 if (step_rate)
415 dw[1] |= GEN8_INSTANCING_DW1_ENABLE;
416 dw[2] = step_rate;
417 }
418
419 static inline void
420 gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
421 bool vid_enable, int vid_ve, int vid_comp,
422 bool iid_enable, int iid_ve, int iid_comp)
423 {
424 const uint8_t cmd_len = 2;
425 uint32_t *dw;
426
427 ILO_DEV_ASSERT(builder->dev, 8, 8);
428
429 ilo_builder_batch_pointer(builder, cmd_len, &dw);
430
431 dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
432 dw[1] = 0;
433
434 if (iid_enable) {
435 dw[1] |= GEN8_SGVS_DW1_IID_ENABLE |
436 vid_comp << GEN8_SGVS_DW1_IID_VE_COMP__SHIFT |
437 vid_ve << GEN8_SGVS_DW1_IID_VE_INDEX__SHIFT;
438 }
439
440 if (vid_enable) {
441 dw[1] |= GEN8_SGVS_DW1_VID_ENABLE |
442 vid_comp << GEN8_SGVS_DW1_VID_VE_COMP__SHIFT |
443 vid_ve << GEN8_SGVS_DW1_VID_VE_INDEX__SHIFT;
444 }
445 }
446
447 static inline void
448 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
449 const struct ilo_ve_state *ve,
450 const struct ilo_vb_state *vb)
451 {
452 uint8_t cmd_len;
453 uint32_t *dw;
454 unsigned pos, hw_idx;
455
456 ILO_DEV_ASSERT(builder->dev, 6, 8);
457
458 /*
459 * From the Sandy Bridge PRM, volume 2 part 1, page 82:
460 *
461 * "From 1 to 33 VBs can be specified..."
462 */
463 assert(ve->vb_count <= 33);
464
465 if (!ve->vb_count)
466 return;
467
468 cmd_len = 1 + 4 * ve->vb_count;
469 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
470
471 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
472 dw++;
473 pos++;
474
475 for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
476 const unsigned instance_divisor = ve->instance_divisors[hw_idx];
477 const unsigned pipe_idx = ve->vb_mapping[hw_idx];
478 const struct pipe_vertex_buffer *cso = &vb->states[pipe_idx];
479
480 dw[0] = hw_idx << GEN6_VB_DW0_INDEX__SHIFT;
481
482 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
483 dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
484 else
485 dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
486
487 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
488 dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
489
490 if (instance_divisor)
491 dw[0] |= GEN6_VB_DW0_ACCESS_INSTANCEDATA;
492 else
493 dw[0] |= GEN6_VB_DW0_ACCESS_VERTEXDATA;
494
495 /* use null vb if there is no buffer or the stride is out of range */
496 if (!cso->buffer || cso->stride > 2048) {
497 dw[0] |= GEN6_VB_DW0_IS_NULL;
498 dw[1] = 0;
499 dw[2] = 0;
500 dw[3] = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ?
501 0 : instance_divisor;
502
503 continue;
504 }
505
506 dw[0] |= cso->stride << GEN6_VB_DW0_PITCH__SHIFT;
507
508 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
509 const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
510 const uint32_t start_offset = cso->buffer_offset;
511
512 ilo_builder_batch_reloc64(builder, pos + 1,
513 buf->bo, start_offset, 0);
514 dw[3] = buf->bo_size;
515 } else {
516 const struct ilo_buffer *buf = ilo_buffer(cso->buffer);
517 const uint32_t start_offset = cso->buffer_offset;
518 const uint32_t end_offset = buf->bo_size - 1;
519
520 dw[3] = instance_divisor;
521
522 ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
523 ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
524 }
525
526 dw += 4;
527 pos += 4;
528 }
529 }
530
531 /* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
532 static inline void
533 gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
534 uint32_t vb_begin, uint32_t vb_end,
535 uint32_t stride)
536 {
537 const struct ilo_builder_writer *bat =
538 &builder->writers[ILO_BUILDER_WRITER_BATCH];
539 const uint8_t cmd_len = 1 + 4;
540 uint32_t *dw;
541 unsigned pos;
542
543 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
544
545 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
546
547 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
548 dw++;
549 pos++;
550
551 /* VERTEX_BUFFER_STATE */
552 dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
553 GEN6_VB_DW0_ACCESS_VERTEXDATA |
554 stride << GEN6_VB_DW0_PITCH__SHIFT;
555 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
556 dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
557
558 dw[3] = 0;
559
560 ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
561 ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
562 }
563
564 static inline void
565 gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
566 const struct ilo_ve_state *ve)
567 {
568 uint8_t cmd_len;
569 uint32_t *dw;
570 unsigned i;
571
572 ILO_DEV_ASSERT(builder->dev, 6, 8);
573
574 /*
575 * From the Sandy Bridge PRM, volume 2 part 1, page 92:
576 *
577 * "At least one VERTEX_ELEMENT_STATE structure must be included."
578 *
579 * From the Sandy Bridge PRM, volume 2 part 1, page 93:
580 *
581 * "Up to 34 (DevSNB+) vertex elements are supported."
582 */
583 assert(ve->count + ve->prepend_nosrc_cso >= 1);
584 assert(ve->count + ve->prepend_nosrc_cso <= 34);
585
586 STATIC_ASSERT(Elements(ve->cso[0].payload) == 2);
587
588 cmd_len = 1 + 2 * (ve->count + ve->prepend_nosrc_cso);
589 ilo_builder_batch_pointer(builder, cmd_len, &dw);
590
591 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
592 dw++;
593
594 if (ve->prepend_nosrc_cso) {
595 memcpy(dw, ve->nosrc_cso.payload, sizeof(ve->nosrc_cso.payload));
596 dw += 2;
597 }
598
599 for (i = 0; i < ve->count - ve->last_cso_edgeflag; i++) {
600 memcpy(dw, ve->cso[i].payload, sizeof(ve->cso[i].payload));
601 dw += 2;
602 }
603
604 if (ve->last_cso_edgeflag)
605 memcpy(dw, ve->edgeflag_cso.payload, sizeof(ve->edgeflag_cso.payload));
606 }
607
608 static inline void
609 gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
610 const struct ilo_ib_state *ib,
611 bool enable_cut_index)
612 {
613 const uint8_t cmd_len = 3;
614 struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
615 uint32_t start_offset, end_offset;
616 int format;
617 uint32_t *dw;
618 unsigned pos;
619
620 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
621
622 if (!buf)
623 return;
624
625 /* this is moved to the new 3DSTATE_VF */
626 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5))
627 assert(!enable_cut_index);
628
629 switch (ib->hw_index_size) {
630 case 4:
631 format = GEN6_IB_DW0_FORMAT_DWORD;
632 break;
633 case 2:
634 format = GEN6_IB_DW0_FORMAT_WORD;
635 break;
636 case 1:
637 format = GEN6_IB_DW0_FORMAT_BYTE;
638 break;
639 default:
640 assert(!"unknown index size");
641 format = GEN6_IB_DW0_FORMAT_BYTE;
642 break;
643 }
644
645 /*
646 * set start_offset to 0 here and adjust pipe_draw_info::start with
647 * ib->draw_start_offset in 3DPRIMITIVE
648 */
649 start_offset = 0;
650 end_offset = buf->bo_size;
651
652 /* end_offset must also be aligned and is inclusive */
653 end_offset -= (end_offset % ib->hw_index_size);
654 end_offset--;
655
656 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
657
658 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
659 builder->mocs << GEN6_IB_DW0_MOCS__SHIFT |
660 format;
661 if (enable_cut_index)
662 dw[0] |= GEN6_IB_DW0_CUT_INDEX_ENABLE;
663
664 ilo_builder_batch_reloc(builder, pos + 1, buf->bo, start_offset, 0);
665 ilo_builder_batch_reloc(builder, pos + 2, buf->bo, end_offset, 0);
666 }
667
668 static inline void
669 gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
670 const struct ilo_ib_state *ib)
671 {
672 const uint8_t cmd_len = 5;
673 struct ilo_buffer *buf = ilo_buffer(ib->hw_resource);
674 int format;
675 uint32_t *dw;
676 unsigned pos;
677
678 ILO_DEV_ASSERT(builder->dev, 8, 8);
679
680 if (!buf)
681 return;
682
683 switch (ib->hw_index_size) {
684 case 4:
685 format = GEN8_IB_DW1_FORMAT_DWORD;
686 break;
687 case 2:
688 format = GEN8_IB_DW1_FORMAT_WORD;
689 break;
690 case 1:
691 format = GEN8_IB_DW1_FORMAT_BYTE;
692 break;
693 default:
694 assert(!"unknown index size");
695 format = GEN8_IB_DW1_FORMAT_BYTE;
696 break;
697 }
698
699 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
700
701 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
702 dw[1] = format |
703 builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
704 dw[4] = buf->bo_size;
705
706 /* ignore ib->offset here in favor of adjusting 3DPRIMITIVE */
707 ilo_builder_batch_reloc64(builder, pos + 2, buf->bo, 0, 0);
708 }
709
710 static inline void
711 gen6_3DSTATE_VS(struct ilo_builder *builder,
712 const struct ilo_shader_state *vs)
713 {
714 const uint8_t cmd_len = 6;
715 const struct ilo_shader_cso *cso;
716 uint32_t dw2, dw4, dw5, *dw;
717
718 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
719
720 cso = ilo_shader_get_kernel_cso(vs);
721 dw2 = cso->payload[0];
722 dw4 = cso->payload[1];
723 dw5 = cso->payload[2];
724
725 ilo_builder_batch_pointer(builder, cmd_len, &dw);
726
727 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
728 dw[1] = ilo_shader_get_kernel_offset(vs);
729 dw[2] = dw2;
730 dw[3] = 0; /* scratch */
731 dw[4] = dw4;
732 dw[5] = dw5;
733 }
734
735 static inline void
736 gen8_3DSTATE_VS(struct ilo_builder *builder,
737 const struct ilo_shader_state *vs,
738 uint32_t clip_plane_enable)
739 {
740 const uint8_t cmd_len = 9;
741 const struct ilo_shader_cso *cso;
742 uint32_t dw3, dw6, dw7, dw8, *dw;
743
744 ILO_DEV_ASSERT(builder->dev, 8, 8);
745
746 cso = ilo_shader_get_kernel_cso(vs);
747 dw3 = cso->payload[0];
748 dw6 = cso->payload[1];
749 dw7 = cso->payload[2];
750 dw8 = clip_plane_enable << GEN8_VS_DW8_UCP_CLIP_ENABLES__SHIFT;
751
752 ilo_builder_batch_pointer(builder, cmd_len, &dw);
753
754 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
755 dw[1] = ilo_shader_get_kernel_offset(vs);
756 dw[2] = 0;
757 dw[3] = dw3;
758 dw[4] = 0; /* scratch */
759 dw[5] = 0;
760 dw[6] = dw6;
761 dw[7] = dw7;
762 dw[8] = dw8;
763 }
764
765 static inline void
766 gen6_disable_3DSTATE_VS(struct ilo_builder *builder)
767 {
768 const uint8_t cmd_len = 6;
769 uint32_t *dw;
770
771 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
772
773 ilo_builder_batch_pointer(builder, cmd_len, &dw);
774
775 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
776 dw[1] = 0;
777 dw[2] = 0;
778 dw[3] = 0;
779 dw[4] = 0;
780 dw[5] = 0;
781 }
782
783 static inline void
784 gen7_disable_3DSTATE_HS(struct ilo_builder *builder)
785 {
786 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 7;
787 uint32_t *dw;
788
789 ILO_DEV_ASSERT(builder->dev, 7, 8);
790
791 ilo_builder_batch_pointer(builder, cmd_len, &dw);
792
793 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
794 dw[1] = 0;
795 dw[2] = 0;
796 dw[3] = 0;
797 dw[4] = 0;
798 dw[5] = 0;
799 dw[6] = 0;
800 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
801 dw[7] = 0;
802 dw[8] = 0;
803 }
804 }
805
806 static inline void
807 gen7_3DSTATE_TE(struct ilo_builder *builder)
808 {
809 const uint8_t cmd_len = 4;
810 uint32_t *dw;
811
812 ILO_DEV_ASSERT(builder->dev, 7, 8);
813
814 ilo_builder_batch_pointer(builder, cmd_len, &dw);
815
816 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
817 dw[1] = 0;
818 dw[2] = 0;
819 dw[3] = 0;
820 }
821
822 static inline void
823 gen7_disable_3DSTATE_DS(struct ilo_builder *builder)
824 {
825 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 9 : 6;
826 uint32_t *dw;
827
828 ILO_DEV_ASSERT(builder->dev, 7, 8);
829
830 ilo_builder_batch_pointer(builder, cmd_len, &dw);
831
832 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
833 dw[1] = 0;
834 dw[2] = 0;
835 dw[3] = 0;
836 dw[4] = 0;
837 dw[5] = 0;
838 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
839 dw[6] = 0;
840 dw[7] = 0;
841 dw[8] = 0;
842 }
843 }
844
845 static inline void
846 gen6_3DSTATE_GS(struct ilo_builder *builder,
847 const struct ilo_shader_state *gs)
848 {
849 const uint8_t cmd_len = 7;
850 const struct ilo_shader_cso *cso;
851 uint32_t dw2, dw4, dw5, dw6, *dw;
852
853 ILO_DEV_ASSERT(builder->dev, 6, 6);
854
855 cso = ilo_shader_get_kernel_cso(gs);
856 dw2 = cso->payload[0];
857 dw4 = cso->payload[1];
858 dw5 = cso->payload[2];
859 dw6 = cso->payload[3];
860
861 ilo_builder_batch_pointer(builder, cmd_len, &dw);
862
863 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
864 dw[1] = ilo_shader_get_kernel_offset(gs);
865 dw[2] = dw2;
866 dw[3] = 0; /* scratch */
867 dw[4] = dw4;
868 dw[5] = dw5;
869 dw[6] = dw6;
870 }
871
872 static inline void
873 gen6_so_3DSTATE_GS(struct ilo_builder *builder,
874 const struct ilo_shader_state *vs,
875 int verts_per_prim)
876 {
877 const uint8_t cmd_len = 7;
878 struct ilo_shader_cso cso;
879 enum ilo_kernel_param param;
880 uint32_t dw2, dw4, dw5, dw6, *dw;
881
882 ILO_DEV_ASSERT(builder->dev, 6, 6);
883
884 assert(ilo_shader_get_kernel_param(vs, ILO_KERNEL_VS_GEN6_SO));
885
886 switch (verts_per_prim) {
887 case 1:
888 param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
889 break;
890 case 2:
891 param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
892 break;
893 default:
894 param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
895 break;
896 }
897
898 /* cannot use VS's CSO */
899 ilo_gpe_init_gs_cso(builder->dev, vs, &cso);
900 dw2 = cso.payload[0];
901 dw4 = cso.payload[1];
902 dw5 = cso.payload[2];
903 dw6 = cso.payload[3];
904
905 ilo_builder_batch_pointer(builder, cmd_len, &dw);
906
907 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
908 dw[1] = ilo_shader_get_kernel_offset(vs) +
909 ilo_shader_get_kernel_param(vs, param);
910 dw[2] = dw2;
911 dw[3] = 0;
912 dw[4] = dw4;
913 dw[5] = dw5;
914 dw[6] = dw6;
915 }
916
917 static inline void
918 gen6_disable_3DSTATE_GS(struct ilo_builder *builder)
919 {
920 const uint8_t cmd_len = 7;
921 uint32_t *dw;
922
923 ILO_DEV_ASSERT(builder->dev, 6, 6);
924
925 ilo_builder_batch_pointer(builder, cmd_len, &dw);
926
927 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
928 dw[1] = 0;
929 dw[2] = 0;
930 dw[3] = 0;
931 /* honor the valid range of URB read length */
932 dw[4] = 1 << GEN6_GS_DW4_URB_READ_LEN__SHIFT;
933 dw[5] = GEN6_GS_DW5_STATISTICS;
934 dw[6] = 0;
935 }
936
937 static inline void
938 gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
939 int index, unsigned svbi,
940 unsigned max_svbi,
941 bool load_vertex_count)
942 {
943 const uint8_t cmd_len = 4;
944 uint32_t *dw;
945
946 ILO_DEV_ASSERT(builder->dev, 6, 6);
947 assert(index >= 0 && index < 4);
948
949 ilo_builder_batch_pointer(builder, cmd_len, &dw);
950
951 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
952
953 dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
954 if (load_vertex_count)
955 dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
956
957 dw[2] = svbi;
958 dw[3] = max_svbi;
959 }
960
961 static inline void
962 gen7_3DSTATE_GS(struct ilo_builder *builder,
963 const struct ilo_shader_state *gs)
964 {
965 const uint8_t cmd_len = 7;
966 const struct ilo_shader_cso *cso;
967 uint32_t dw2, dw4, dw5, *dw;
968
969 ILO_DEV_ASSERT(builder->dev, 7, 7.5);
970
971 cso = ilo_shader_get_kernel_cso(gs);
972 dw2 = cso->payload[0];
973 dw4 = cso->payload[1];
974 dw5 = cso->payload[2];
975
976 ilo_builder_batch_pointer(builder, cmd_len, &dw);
977
978 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
979 dw[1] = ilo_shader_get_kernel_offset(gs);
980 dw[2] = dw2;
981 dw[3] = 0; /* scratch */
982 dw[4] = dw4;
983 dw[5] = dw5;
984 dw[6] = 0;
985 }
986
987 static inline void
988 gen7_disable_3DSTATE_GS(struct ilo_builder *builder)
989 {
990 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 10 : 7;
991 uint32_t *dw;
992
993 ILO_DEV_ASSERT(builder->dev, 7, 8);
994
995 ilo_builder_batch_pointer(builder, cmd_len, &dw);
996
997 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
998 dw[1] = 0;
999 dw[2] = 0;
1000 dw[3] = 0;
1001 dw[4] = 0;
1002
1003 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1004 dw[7] = GEN8_GS_DW7_STATISTICS;
1005 dw[8] = 0;
1006 dw[9] = 0;
1007 } else {
1008 dw[5] = GEN7_GS_DW5_STATISTICS;
1009 dw[6] = 0;
1010 }
1011 }
1012
1013 static inline void
1014 gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
1015 int render_stream,
1016 bool render_disable,
1017 int vertex_attrib_count,
1018 const int *buf_strides)
1019 {
1020 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
1021 uint32_t *dw;
1022 int buf_mask;
1023
1024 ILO_DEV_ASSERT(builder->dev, 7, 8);
1025
1026 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1027
1028 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
1029
1030 dw[1] = render_stream << GEN7_SO_DW1_RENDER_STREAM_SELECT__SHIFT;
1031 if (render_disable)
1032 dw[1] |= GEN7_SO_DW1_RENDER_DISABLE;
1033
1034 if (buf_strides) {
1035 buf_mask = ((bool) buf_strides[3]) << 3 |
1036 ((bool) buf_strides[2]) << 2 |
1037 ((bool) buf_strides[1]) << 1 |
1038 ((bool) buf_strides[0]);
1039 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1040 dw[3] = buf_strides[1] << 16 | buf_strides[0];
1041 dw[4] = buf_strides[3] << 16 | buf_strides[1];
1042 }
1043 } else {
1044 buf_mask = 0;
1045 }
1046
1047 if (buf_mask) {
1048 int read_len;
1049
1050 dw[1] |= GEN7_SO_DW1_SO_ENABLE |
1051 GEN7_SO_DW1_STATISTICS;
1052 /* API_OPENGL */
1053 if (true)
1054 dw[1] |= GEN7_REORDER_TRAILING << GEN7_SO_DW1_REORDER_MODE__SHIFT;
1055 if (ilo_dev_gen(builder->dev) < ILO_GEN(8))
1056 dw[1] |= buf_mask << GEN7_SO_DW1_BUFFER_ENABLES__SHIFT;
1057
1058 read_len = (vertex_attrib_count + 1) / 2;
1059 if (!read_len)
1060 read_len = 1;
1061
1062 dw[2] = 0 << GEN7_SO_DW2_STREAM3_READ_OFFSET__SHIFT |
1063 (read_len - 1) << GEN7_SO_DW2_STREAM3_READ_LEN__SHIFT |
1064 0 << GEN7_SO_DW2_STREAM2_READ_OFFSET__SHIFT |
1065 (read_len - 1) << GEN7_SO_DW2_STREAM2_READ_LEN__SHIFT |
1066 0 << GEN7_SO_DW2_STREAM1_READ_OFFSET__SHIFT |
1067 (read_len - 1) << GEN7_SO_DW2_STREAM1_READ_LEN__SHIFT |
1068 0 << GEN7_SO_DW2_STREAM0_READ_OFFSET__SHIFT |
1069 (read_len - 1) << GEN7_SO_DW2_STREAM0_READ_LEN__SHIFT;
1070 } else {
1071 dw[2] = 0;
1072 }
1073 }
1074
1075 static inline void
1076 gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
1077 const struct pipe_stream_output_info *so_info)
1078 {
1079 /*
1080 * Note that "DWord Length" has 9 bits for this command and the type of
1081 * cmd_len cannot be uint8_t.
1082 */
1083 uint16_t cmd_len;
1084 struct {
1085 int buf_selects;
1086 int decl_count;
1087 uint16_t decls[128];
1088 } streams[4];
1089 unsigned buf_offsets[PIPE_MAX_SO_BUFFERS];
1090 int hw_decl_count, i;
1091 uint32_t *dw;
1092
1093 ILO_DEV_ASSERT(builder->dev, 7, 8);
1094
1095 memset(streams, 0, sizeof(streams));
1096 memset(buf_offsets, 0, sizeof(buf_offsets));
1097
1098 for (i = 0; i < so_info->num_outputs; i++) {
1099 unsigned decl, st, buf, reg, mask;
1100
1101 st = so_info->output[i].stream;
1102 buf = so_info->output[i].output_buffer;
1103
1104 /* pad with holes */
1105 while (buf_offsets[buf] < so_info->output[i].dst_offset) {
1106 int num_dwords;
1107
1108 num_dwords = so_info->output[i].dst_offset - buf_offsets[buf];
1109 if (num_dwords > 4)
1110 num_dwords = 4;
1111
1112 decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
1113 GEN7_SO_DECL_HOLE_FLAG |
1114 ((1 << num_dwords) - 1) << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
1115
1116 assert(streams[st].decl_count < Elements(streams[st].decls));
1117 streams[st].decls[streams[st].decl_count++] = decl;
1118 buf_offsets[buf] += num_dwords;
1119 }
1120 assert(buf_offsets[buf] == so_info->output[i].dst_offset);
1121
1122 reg = so_info->output[i].register_index;
1123 mask = ((1 << so_info->output[i].num_components) - 1) <<
1124 so_info->output[i].start_component;
1125
1126 decl = buf << GEN7_SO_DECL_OUTPUT_SLOT__SHIFT |
1127 reg << GEN7_SO_DECL_REG_INDEX__SHIFT |
1128 mask << GEN7_SO_DECL_COMPONENT_MASK__SHIFT;
1129
1130 assert(streams[st].decl_count < Elements(streams[st].decls));
1131
1132 streams[st].buf_selects |= 1 << buf;
1133 streams[st].decls[streams[st].decl_count++] = decl;
1134 buf_offsets[buf] += so_info->output[i].num_components;
1135 }
1136
1137 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
1138 hw_decl_count = MAX4(streams[0].decl_count, streams[1].decl_count,
1139 streams[2].decl_count, streams[3].decl_count);
1140 } else {
1141 /*
1142 * From the Ivy Bridge PRM, volume 2 part 1, page 201:
1143 *
1144 * "Errata: All 128 decls for all four streams must be included
1145 * whenever this command is issued. The "Num Entries [n]" fields
1146 * still contain the actual numbers of valid decls."
1147 */
1148 hw_decl_count = 128;
1149 }
1150
1151 cmd_len = 3 + 2 * hw_decl_count;
1152
1153 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1154
1155 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
1156 dw[1] = streams[3].buf_selects << GEN7_SO_DECL_DW1_STREAM3_BUFFER_SELECTS__SHIFT |
1157 streams[2].buf_selects << GEN7_SO_DECL_DW1_STREAM2_BUFFER_SELECTS__SHIFT |
1158 streams[1].buf_selects << GEN7_SO_DECL_DW1_STREAM1_BUFFER_SELECTS__SHIFT |
1159 streams[0].buf_selects << GEN7_SO_DECL_DW1_STREAM0_BUFFER_SELECTS__SHIFT;
1160 dw[2] = streams[3].decl_count << GEN7_SO_DECL_DW2_STREAM3_ENTRY_COUNT__SHIFT |
1161 streams[2].decl_count << GEN7_SO_DECL_DW2_STREAM2_ENTRY_COUNT__SHIFT |
1162 streams[1].decl_count << GEN7_SO_DECL_DW2_STREAM1_ENTRY_COUNT__SHIFT |
1163 streams[0].decl_count << GEN7_SO_DECL_DW2_STREAM0_ENTRY_COUNT__SHIFT;
1164 dw += 3;
1165
1166 for (i = 0; i < hw_decl_count; i++) {
1167 dw[0] = streams[1].decls[i] << 16 | streams[0].decls[i];
1168 dw[1] = streams[3].decls[i] << 16 | streams[2].decls[i];
1169 dw += 2;
1170 }
1171 }
1172
1173 static inline void
1174 gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index, int stride,
1175 const struct pipe_stream_output_target *so_target)
1176 {
1177 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
1178 struct ilo_buffer *buf;
1179 int start, end;
1180 uint32_t *dw;
1181 unsigned pos;
1182
1183 ILO_DEV_ASSERT(builder->dev, 7, 8);
1184
1185 buf = ilo_buffer(so_target->buffer);
1186
1187 /* DWord-aligned */
1188 assert(stride % 4 == 0);
1189 assert(so_target->buffer_offset % 4 == 0);
1190
1191 stride &= ~3;
1192 start = so_target->buffer_offset & ~3;
1193 end = (start + so_target->buffer_size) & ~3;
1194
1195 pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
1196
1197 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
1198 dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT |
1199 stride;
1200
1201 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1202 dw[1] |= builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
1203
1204 dw[4] = end - start;
1205 dw[5] = 0;
1206 dw[6] = 0;
1207 dw[7] = 0;
1208
1209 ilo_builder_batch_reloc64(builder, pos + 2,
1210 buf->bo, start, INTEL_RELOC_WRITE);
1211 } else {
1212 dw[1] |= builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT;
1213
1214 ilo_builder_batch_reloc(builder, pos + 2,
1215 buf->bo, start, INTEL_RELOC_WRITE);
1216 ilo_builder_batch_reloc(builder, pos + 3,
1217 buf->bo, end, INTEL_RELOC_WRITE);
1218 }
1219 }
1220
1221 static inline void
1222 gen7_disable_3DSTATE_SO_BUFFER(struct ilo_builder *builder, int index)
1223 {
1224 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 8 : 4;
1225 uint32_t *dw;
1226
1227 ILO_DEV_ASSERT(builder->dev, 7, 8);
1228
1229 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1230
1231 dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
1232 dw[1] = index << GEN7_SO_BUF_DW1_INDEX__SHIFT;
1233 dw[2] = 0;
1234 dw[3] = 0;
1235
1236 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1237 dw[4] = 0;
1238 dw[5] = 0;
1239 dw[6] = 0;
1240 dw[7] = 0;
1241 }
1242 }
1243
1244 static inline void
1245 gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
1246 uint32_t vs_binding_table,
1247 uint32_t gs_binding_table,
1248 uint32_t ps_binding_table)
1249 {
1250 const uint8_t cmd_len = 4;
1251 uint32_t *dw;
1252
1253 ILO_DEV_ASSERT(builder->dev, 6, 6);
1254
1255 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1256
1257 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
1258 GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
1259 GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
1260 GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
1261 (cmd_len - 2);
1262 dw[1] = vs_binding_table;
1263 dw[2] = gs_binding_table;
1264 dw[3] = ps_binding_table;
1265 }
1266
1267 static inline void
1268 gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
1269 uint32_t vs_sampler_state,
1270 uint32_t gs_sampler_state,
1271 uint32_t ps_sampler_state)
1272 {
1273 const uint8_t cmd_len = 4;
1274 uint32_t *dw;
1275
1276 ILO_DEV_ASSERT(builder->dev, 6, 6);
1277
1278 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1279
1280 dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
1281 GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
1282 GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
1283 GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
1284 (cmd_len - 2);
1285 dw[1] = vs_sampler_state;
1286 dw[2] = gs_sampler_state;
1287 dw[3] = ps_sampler_state;
1288 }
1289
1290 static inline void
1291 gen7_3dstate_pointer(struct ilo_builder *builder,
1292 int subop, uint32_t pointer)
1293 {
1294 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1295 GEN6_RENDER_SUBTYPE_3D |
1296 subop;
1297 const uint8_t cmd_len = 2;
1298 uint32_t *dw;
1299
1300 ILO_DEV_ASSERT(builder->dev, 7, 8);
1301
1302 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1303
1304 dw[0] = cmd | (cmd_len - 2);
1305 dw[1] = pointer;
1306 }
1307
1308 static inline void
1309 gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
1310 uint32_t binding_table)
1311 {
1312 gen7_3dstate_pointer(builder,
1313 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
1314 binding_table);
1315 }
1316
1317 static inline void
1318 gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
1319 uint32_t binding_table)
1320 {
1321 gen7_3dstate_pointer(builder,
1322 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
1323 binding_table);
1324 }
1325
1326 static inline void
1327 gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
1328 uint32_t binding_table)
1329 {
1330 gen7_3dstate_pointer(builder,
1331 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
1332 binding_table);
1333 }
1334
1335 static inline void
1336 gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
1337 uint32_t binding_table)
1338 {
1339 gen7_3dstate_pointer(builder,
1340 GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
1341 binding_table);
1342 }
1343
1344 static inline void
1345 gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
1346 uint32_t sampler_state)
1347 {
1348 gen7_3dstate_pointer(builder,
1349 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
1350 sampler_state);
1351 }
1352
1353 static inline void
1354 gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
1355 uint32_t sampler_state)
1356 {
1357 gen7_3dstate_pointer(builder,
1358 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
1359 sampler_state);
1360 }
1361
1362 static inline void
1363 gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
1364 uint32_t sampler_state)
1365 {
1366 gen7_3dstate_pointer(builder,
1367 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
1368 sampler_state);
1369 }
1370
1371 static inline void
1372 gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
1373 uint32_t sampler_state)
1374 {
1375 gen7_3dstate_pointer(builder,
1376 GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
1377 sampler_state);
1378 }
1379
1380 static inline void
1381 gen6_3dstate_constant(struct ilo_builder *builder, int subop,
1382 const uint32_t *bufs, const int *sizes,
1383 int num_bufs)
1384 {
1385 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1386 GEN6_RENDER_SUBTYPE_3D |
1387 subop;
1388 const uint8_t cmd_len = 5;
1389 unsigned buf_enabled = 0x0;
1390 uint32_t buf_dw[4], *dw;
1391 int max_read_length, total_read_length;
1392 int i;
1393
1394 ILO_DEV_ASSERT(builder->dev, 6, 6);
1395
1396 assert(num_bufs <= 4);
1397
1398 /*
1399 * From the Sandy Bridge PRM, volume 2 part 1, page 138:
1400 *
1401 * "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
1402 * incremented to represent the actual read length) must be less than
1403 * or equal to 32"
1404 *
1405 * From the Sandy Bridge PRM, volume 2 part 1, page 161:
1406 *
1407 * "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
1408 * incremented to represent the actual read length) must be less than
1409 * or equal to 64"
1410 *
1411 * From the Sandy Bridge PRM, volume 2 part 1, page 287:
1412 *
1413 * "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
1414 * incremented to represent the actual read length) must be less than
1415 * or equal to 64"
1416 */
1417 switch (subop) {
1418 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
1419 max_read_length = 32;
1420 break;
1421 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
1422 case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
1423 max_read_length = 64;
1424 break;
1425 default:
1426 assert(!"unknown pcb subop");
1427 max_read_length = 0;
1428 break;
1429 }
1430
1431 total_read_length = 0;
1432 for (i = 0; i < 4; i++) {
1433 if (i < num_bufs && sizes[i]) {
1434 /* in 256-bit units */
1435 const int read_len = (sizes[i] + 31) / 32;
1436
1437 assert(bufs[i] % 32 == 0);
1438 assert(read_len <= 32);
1439
1440 buf_enabled |= 1 << i;
1441 buf_dw[i] = bufs[i] | (read_len - 1);
1442
1443 total_read_length += read_len;
1444 } else {
1445 buf_dw[i] = 0;
1446 }
1447 }
1448
1449 assert(total_read_length <= max_read_length);
1450
1451 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1452
1453 dw[0] = cmd | (cmd_len - 2) |
1454 buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
1455 builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
1456
1457 memcpy(&dw[1], buf_dw, sizeof(buf_dw));
1458 }
1459
1460 static inline void
1461 gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1462 const uint32_t *bufs, const int *sizes,
1463 int num_bufs)
1464 {
1465 gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1466 bufs, sizes, num_bufs);
1467 }
1468
1469 static inline void
1470 gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1471 const uint32_t *bufs, const int *sizes,
1472 int num_bufs)
1473 {
1474 gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1475 bufs, sizes, num_bufs);
1476 }
1477
1478 static inline void
1479 gen7_3dstate_constant(struct ilo_builder *builder,
1480 int subop,
1481 const uint32_t *bufs, const int *sizes,
1482 int num_bufs)
1483 {
1484 const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1485 GEN6_RENDER_SUBTYPE_3D |
1486 subop;
1487 const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
1488 uint32_t payload[6], *dw;
1489 int total_read_length, i;
1490
1491 ILO_DEV_ASSERT(builder->dev, 7, 8);
1492
1493 /* VS, HS, DS, GS, and PS variants */
1494 assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
1495 subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
1496 subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
1497
1498 assert(num_bufs <= 4);
1499
1500 payload[0] = 0;
1501 payload[1] = 0;
1502
1503 total_read_length = 0;
1504 for (i = 0; i < 4; i++) {
1505 int read_len;
1506
1507 /*
1508 * From the Ivy Bridge PRM, volume 2 part 1, page 112:
1509 *
1510 * "Constant buffers must be enabled in order from Constant Buffer 0
1511 * to Constant Buffer 3 within this command. For example, it is
1512 * not allowed to enable Constant Buffer 1 by programming a
1513 * non-zero value in the VS Constant Buffer 1 Read Length without a
1514 * non-zero value in VS Constant Buffer 0 Read Length."
1515 */
1516 if (i >= num_bufs || !sizes[i]) {
1517 for (; i < 4; i++) {
1518 assert(i >= num_bufs || !sizes[i]);
1519 payload[2 + i] = 0;
1520 }
1521 break;
1522 }
1523
1524 /* read lengths are in 256-bit units */
1525 read_len = (sizes[i] + 31) / 32;
1526 /* the lower 5 bits are used for memory object control state */
1527 assert(bufs[i] % 32 == 0);
1528
1529 payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
1530 payload[2 + i] = bufs[i];
1531
1532 total_read_length += read_len;
1533 }
1534
1535 /*
1536 * From the Ivy Bridge PRM, volume 2 part 1, page 113:
1537 *
1538 * "The sum of all four read length fields must be less than or equal
1539 * to the size of 64"
1540 */
1541 assert(total_read_length <= 64);
1542
1543 ilo_builder_batch_pointer(builder, cmd_len, &dw);
1544
1545 dw[0] = cmd | (cmd_len - 2);
1546 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1547 dw[1] = payload[0];
1548 dw[2] = payload[1];
1549 dw[3] = payload[2];
1550 dw[4] = 0;
1551 dw[5] = payload[3];
1552 dw[6] = 0;
1553 dw[7] = payload[4];
1554 dw[8] = 0;
1555 dw[9] = payload[5];
1556 dw[10] = 0;
1557 } else {
1558 payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
1559
1560 memcpy(&dw[1], payload, sizeof(payload));
1561 }
1562 }
1563
1564 static inline void
1565 gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1566 const uint32_t *bufs, const int *sizes,
1567 int num_bufs)
1568 {
1569 gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1570 bufs, sizes, num_bufs);
1571 }
1572
1573 static inline void
1574 gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
1575 const uint32_t *bufs, const int *sizes,
1576 int num_bufs)
1577 {
1578 gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
1579 bufs, sizes, num_bufs);
1580 }
1581
1582 static inline void
1583 gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
1584 const uint32_t *bufs, const int *sizes,
1585 int num_bufs)
1586 {
1587 gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
1588 bufs, sizes, num_bufs);
1589 }
1590
1591 static inline void
1592 gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1593 const uint32_t *bufs, const int *sizes,
1594 int num_bufs)
1595 {
1596 gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1597 bufs, sizes, num_bufs);
1598 }
1599
1600 static inline uint32_t
1601 gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
1602 const uint32_t *surface_states,
1603 int num_surface_states)
1604 {
1605 const int state_align = 32;
1606 const int state_len = num_surface_states;
1607 uint32_t state_offset, *dw;
1608
1609 ILO_DEV_ASSERT(builder->dev, 6, 8);
1610
1611 /*
1612 * From the Sandy Bridge PRM, volume 4 part 1, page 69:
1613 *
1614 * "It is stored as an array of up to 256 elements..."
1615 */
1616 assert(num_surface_states <= 256);
1617
1618 if (!num_surface_states)
1619 return 0;
1620
1621 state_offset = ilo_builder_surface_pointer(builder,
1622 ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
1623 memcpy(dw, surface_states, state_len << 2);
1624
1625 return state_offset;
1626 }
1627
1628 static inline uint32_t
1629 gen6_SURFACE_STATE(struct ilo_builder *builder,
1630 const struct ilo_state_surface *surf)
1631 {
1632 int state_align, state_len;
1633 uint32_t state_offset, *dw;
1634
1635 ILO_DEV_ASSERT(builder->dev, 6, 8);
1636
1637 if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1638 state_align = 64;
1639 state_len = 13;
1640
1641 state_offset = ilo_builder_surface_pointer(builder,
1642 ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
1643 memcpy(dw, surf->surface, state_len << 2);
1644
1645 if (surf->bo) {
1646 const uint32_t mocs = (surf->scanout) ?
1647 (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
1648
1649 dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
1650
1651 ilo_builder_surface_reloc64(builder, state_offset, 8, surf->bo,
1652 surf->surface[8], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
1653 }
1654 } else {
1655 state_align = 32;
1656 state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 8 : 6;
1657
1658 state_offset = ilo_builder_surface_pointer(builder,
1659 ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
1660 memcpy(dw, surf->surface, state_len << 2);
1661
1662 if (surf->bo) {
1663 /*
1664 * For scanouts, we should not enable caching in LLC. Since we only
1665 * enable that on Gen8+, we are fine here.
1666 */
1667 dw[5] |= builder->mocs << GEN6_SURFACE_DW5_MOCS__SHIFT;
1668
1669 ilo_builder_surface_reloc(builder, state_offset, 1, surf->bo,
1670 surf->surface[1], (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
1671 }
1672 }
1673
1674 return state_offset;
1675 }
1676
1677 static inline uint32_t
1678 gen6_so_SURFACE_STATE(struct ilo_builder *builder,
1679 const struct pipe_stream_output_target *so,
1680 const struct pipe_stream_output_info *so_info,
1681 int so_index)
1682 {
1683 struct ilo_buffer *buf = ilo_buffer(so->buffer);
1684 struct ilo_state_surface_buffer_info info;
1685 struct ilo_state_surface surf;
1686
1687 ILO_DEV_ASSERT(builder->dev, 6, 6);
1688
1689 memset(&info, 0, sizeof(info));
1690 info.buf = buf;
1691 info.access = ILO_STATE_SURFACE_ACCESS_DP_SVB;
1692
1693 switch (so_info->output[so_index].num_components) {
1694 case 1:
1695 info.format = GEN6_FORMAT_R32_FLOAT;
1696 info.format_size = 4;
1697 break;
1698 case 2:
1699 info.format = GEN6_FORMAT_R32G32_FLOAT;
1700 info.format_size = 8;
1701 break;
1702 case 3:
1703 info.format = GEN6_FORMAT_R32G32B32_FLOAT;
1704 info.format_size = 12;
1705 break;
1706 case 4:
1707 info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
1708 info.format_size = 16;
1709 break;
1710 default:
1711 assert(!"unexpected SO components length");
1712 info.format = GEN6_FORMAT_R32_FLOAT;
1713 info.format_size = 4;
1714 break;
1715 }
1716
1717 info.struct_size =
1718 so_info->stride[so_info->output[so_index].output_buffer] * 4;
1719 info.offset = so->buffer_offset + so_info->output[so_index].dst_offset * 4;
1720 info.size = so->buffer_size - so_info->output[so_index].dst_offset * 4;
1721
1722 memset(&surf, 0, sizeof(surf));
1723 ilo_state_surface_init_for_buffer(&surf, builder->dev, &info);
1724 surf.bo = info.buf->bo;
1725
1726 return gen6_SURFACE_STATE(builder, &surf);
1727 }
1728
1729 static inline uint32_t
1730 gen6_SAMPLER_STATE(struct ilo_builder *builder,
1731 const struct ilo_sampler_cso * const *samplers,
1732 const struct pipe_sampler_view * const *views,
1733 const uint32_t *sampler_border_colors,
1734 int num_samplers)
1735 {
1736 const int state_align = 32;
1737 const int state_len = 4 * num_samplers;
1738 uint32_t state_offset, *dw;
1739 int i;
1740
1741 ILO_DEV_ASSERT(builder->dev, 6, 8);
1742
1743 /*
1744 * From the Sandy Bridge PRM, volume 4 part 1, page 101:
1745 *
1746 * "The sampler state is stored as an array of up to 16 elements..."
1747 */
1748 assert(num_samplers <= 16);
1749
1750 if (!num_samplers)
1751 return 0;
1752
1753 /*
1754 * From the Sandy Bridge PRM, volume 2 part 1, page 132:
1755 *
1756 * "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
1757 * multiples of 4) the vertex shader 0 kernel uses. Used only for
1758 * prefetching the associated sampler state entries.
1759 *
1760 * It also applies to other shader stages.
1761 */
1762 ilo_builder_dynamic_pad_top(builder, 4 * (4 - (num_samplers % 4)));
1763
1764 state_offset = ilo_builder_dynamic_pointer(builder,
1765 ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
1766
1767 for (i = 0; i < num_samplers; i++) {
1768 const struct ilo_sampler_cso *sampler = samplers[i];
1769 const struct pipe_sampler_view *view = views[i];
1770 const uint32_t border_color = sampler_border_colors[i];
1771 uint32_t dw_filter, dw_wrap;
1772
1773 /* there may be holes */
1774 if (!sampler || !view) {
1775 /* disabled sampler */
1776 dw[0] = 1 << 31;
1777 dw[1] = 0;
1778 dw[2] = 0;
1779 dw[3] = 0;
1780 dw += 4;
1781
1782 continue;
1783 }
1784
1785 /* determine filter and wrap modes */
1786 switch (view->texture->target) {
1787 case PIPE_TEXTURE_1D:
1788 dw_filter = (sampler->anisotropic) ?
1789 sampler->dw_filter_aniso : sampler->dw_filter;
1790 dw_wrap = sampler->dw_wrap_1d;
1791 break;
1792 case PIPE_TEXTURE_3D:
1793 /*
1794 * From the Sandy Bridge PRM, volume 4 part 1, page 103:
1795 *
1796 * "Only MAPFILTER_NEAREST and MAPFILTER_LINEAR are supported for
1797 * surfaces of type SURFTYPE_3D."
1798 */
1799 dw_filter = sampler->dw_filter;
1800 dw_wrap = sampler->dw_wrap;
1801 break;
1802 case PIPE_TEXTURE_CUBE:
1803 dw_filter = (sampler->anisotropic) ?
1804 sampler->dw_filter_aniso : sampler->dw_filter;
1805 dw_wrap = sampler->dw_wrap_cube;
1806 break;
1807 default:
1808 dw_filter = (sampler->anisotropic) ?
1809 sampler->dw_filter_aniso : sampler->dw_filter;
1810 dw_wrap = sampler->dw_wrap;
1811 break;
1812 }
1813
1814 dw[0] = sampler->payload[0];
1815 dw[1] = sampler->payload[1];
1816 assert(!(border_color & 0x1f));
1817 dw[2] = border_color;
1818 dw[3] = sampler->payload[2];
1819
1820 dw[0] |= dw_filter;
1821
1822 if (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) {
1823 dw[3] |= dw_wrap;
1824 }
1825 else {
1826 /*
1827 * From the Sandy Bridge PRM, volume 4 part 1, page 21:
1828 *
1829 * "[DevSNB] Errata: Incorrect behavior is observed in cases
1830 * where the min and mag mode filters are different and
1831 * SurfMinLOD is nonzero. The determination of MagMode uses the
1832 * following equation instead of the one in the above
1833 * pseudocode: MagMode = (LOD + SurfMinLOD - Base <= 0)"
1834 *
1835 * As a way to work around that, we set Base to
1836 * view->u.tex.first_level.
1837 */
1838 dw[0] |= view->u.tex.first_level << 22;
1839
1840 dw[1] |= dw_wrap;
1841 }
1842
1843 dw += 4;
1844 }
1845
1846 return state_offset;
1847 }
1848
1849 static inline uint32_t
1850 gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
1851 const struct ilo_sampler_cso *sampler)
1852 {
1853 const int state_align =
1854 (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
1855 const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
1856
1857 ILO_DEV_ASSERT(builder->dev, 6, 8);
1858
1859 assert(Elements(sampler->payload) >= 3 + state_len);
1860
1861 /* see ilo_gpe_init_sampler_cso() */
1862 return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1863 state_align, state_len, &sampler->payload[3]);
1864 }
1865
1866 static inline uint32_t
1867 gen6_push_constant_buffer(struct ilo_builder *builder,
1868 int size, void **pcb)
1869 {
1870 /*
1871 * For all VS, GS, FS, and CS push constant buffers, they must be aligned
1872 * to 32 bytes, and their sizes are specified in 256-bit units.
1873 */
1874 const int state_align = 32;
1875 const int state_len = align(size, 32) / 4;
1876 uint32_t state_offset;
1877 char *buf;
1878
1879 ILO_DEV_ASSERT(builder->dev, 6, 8);
1880
1881 state_offset = ilo_builder_dynamic_pointer(builder,
1882 ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
1883
1884 /* zero out the unused range */
1885 if (size < state_len * 4)
1886 memset(&buf[size], 0, state_len * 4 - size);
1887
1888 if (pcb)
1889 *pcb = buf;
1890
1891 return state_offset;
1892 }
1893
1894 static inline uint32_t
1895 gen6_user_vertex_buffer(struct ilo_builder *builder,
1896 int size, const void *vertices)
1897 {
1898 const int state_align = 8;
1899 const int state_len = size / 4;
1900
1901 ILO_DEV_ASSERT(builder->dev, 6, 7.5);
1902
1903 assert(size % 4 == 0);
1904
1905 return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1906 state_align, state_len, vertices);
1907 }
1908
1909 #endif /* ILO_BUILDER_3D_TOP_H */