• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "intel_winsys.h"
33 
34 #include "ilo_core.h"
35 #include "ilo_dev.h"
36 #include "ilo_state_sampler.h"
37 #include "ilo_state_shader.h"
38 #include "ilo_state_sol.h"
39 #include "ilo_state_surface.h"
40 #include "ilo_state_urb.h"
41 #include "ilo_state_vf.h"
42 #include "ilo_vma.h"
43 #include "ilo_builder.h"
44 
45 static inline void
gen6_3DSTATE_URB(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_PUSH_CONSTANT_ALLOC_HS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_PUSH_CONSTANT_ALLOC_DS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_URB_VS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_URB_HS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_URB_DS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen7_3DSTATE_URB_GS(struct ilo_builder * builder,const struct ilo_state_urb * urb)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
gen75_3DSTATE_VF(struct ilo_builder * builder,const struct ilo_state_vf * vf)192 gen75_3DSTATE_VF(struct ilo_builder *builder,
193                  const struct ilo_state_vf *vf)
194 {
195    const uint8_t cmd_len = 2;
196    uint32_t *dw;
197 
198    ILO_DEV_ASSERT(builder->dev, 7.5, 8);
199 
200    ilo_builder_batch_pointer(builder, cmd_len, &dw);
201 
202    /* see vf_params_set_gen75_3DSTATE_VF() */
203    dw[0] = GEN75_RENDER_CMD(3D, 3DSTATE_VF) | (cmd_len - 2) |
204            vf->cut[0];
205    dw[1] = vf->cut[1];
206 }
207 
208 static inline void
gen6_3DSTATE_VF_STATISTICS(struct ilo_builder * builder,bool enable)209 gen6_3DSTATE_VF_STATISTICS(struct ilo_builder *builder,
210                            bool enable)
211 {
212    const uint8_t cmd_len = 1;
213    const uint32_t dw0 = GEN6_RENDER_CMD(SINGLE_DW, 3DSTATE_VF_STATISTICS) |
214                         enable;
215 
216    ILO_DEV_ASSERT(builder->dev, 6, 8);
217 
218    ilo_builder_batch_write(builder, cmd_len, &dw0);
219 }
220 
221 static inline void
gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder * builder,enum gen_3dprim_type topology)222 gen8_3DSTATE_VF_TOPOLOGY(struct ilo_builder *builder,
223                          enum gen_3dprim_type topology)
224 {
225    const uint8_t cmd_len = 2;
226    uint32_t *dw;
227 
228    ILO_DEV_ASSERT(builder->dev, 8, 8);
229 
230    ilo_builder_batch_pointer(builder, cmd_len, &dw);
231 
232    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_TOPOLOGY) | (cmd_len - 2);
233    dw[1] = topology << GEN8_TOPOLOGY_DW1_TYPE__SHIFT;
234 }
235 
236 static inline void
gen8_3DSTATE_VF_INSTANCING(struct ilo_builder * builder,const struct ilo_state_vf * vf,uint32_t attr)237 gen8_3DSTATE_VF_INSTANCING(struct ilo_builder *builder,
238                            const struct ilo_state_vf *vf,
239                            uint32_t attr)
240 {
241    const uint8_t cmd_len = 3;
242    uint32_t *dw;
243 
244    ILO_DEV_ASSERT(builder->dev, 8, 8);
245 
246    ilo_builder_batch_pointer(builder, cmd_len, &dw);
247 
248    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_INSTANCING) | (cmd_len - 2);
249    dw[1] = attr << GEN8_INSTANCING_DW1_VE_INDEX__SHIFT;
250    dw[2] = 0;
251    /* see vf_set_gen8_3DSTATE_VF_INSTANCING() */
252    if (attr >= vf->internal_ve_count) {
253       attr -= vf->internal_ve_count;
254 
255       dw[1] |= vf->user_instancing[attr][0];
256       dw[2] |= vf->user_instancing[attr][1];
257    }
258 }
259 
260 static inline void
gen8_3DSTATE_VF_SGVS(struct ilo_builder * builder,const struct ilo_state_vf * vf)261 gen8_3DSTATE_VF_SGVS(struct ilo_builder *builder,
262                      const struct ilo_state_vf *vf)
263 {
264    const uint8_t cmd_len = 2;
265    uint32_t *dw;
266 
267    ILO_DEV_ASSERT(builder->dev, 8, 8);
268 
269    ilo_builder_batch_pointer(builder, cmd_len, &dw);
270 
271    dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_VF_SGVS) | (cmd_len - 2);
272    /* see vf_params_set_gen8_3DSTATE_VF_SGVS() */
273    dw[1] = vf->sgvs[0];
274 }
275 
276 static inline void
gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder * builder,const struct ilo_state_vf * vf,const struct ilo_state_vertex_buffer * vb,unsigned vb_count)277 gen6_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
278                             const struct ilo_state_vf *vf,
279                             const struct ilo_state_vertex_buffer *vb,
280                             unsigned vb_count)
281 {
282    uint8_t cmd_len;
283    uint32_t *dw;
284    unsigned pos, i;
285 
286    ILO_DEV_ASSERT(builder->dev, 6, 8);
287 
288    /*
289     * From the Sandy Bridge PRM, volume 2 part 1, page 82:
290     *
291     *     "From 1 to 33 VBs can be specified..."
292     */
293    assert(vb_count <= 33);
294 
295    if (!vb_count)
296       return;
297 
298    cmd_len = 1 + 4 * vb_count;
299    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
300 
301    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
302    dw++;
303    pos++;
304 
305    for (i = 0; i < vb_count; i++) {
306       const struct ilo_state_vertex_buffer *b = &vb[i];
307 
308       /* see vertex_buffer_set_gen8_vertex_buffer_state() */
309       dw[0] = b->vb[0] |
310               i << GEN6_VB_DW0_INDEX__SHIFT;
311 
312       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8))
313          dw[0] |= builder->mocs << GEN8_VB_DW0_MOCS__SHIFT;
314       else
315          dw[0] |= builder->mocs << GEN6_VB_DW0_MOCS__SHIFT;
316 
317       dw[1] = 0;
318       dw[2] = 0;
319       dw[3] = 0;
320 
321       if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
322          if (b->vma) {
323             ilo_builder_batch_reloc64(builder, pos + 1, b->vma->bo,
324                   b->vma->bo_offset + b->vb[1], 0);
325          }
326 
327          dw[3] |= b->vb[2];
328       } else {
329          const int8_t elem = vf->vb_to_first_elem[i];
330 
331          /* see vf_set_gen6_vertex_buffer_state() */
332          if (elem >= 0) {
333             dw[0] |= vf->user_instancing[elem][0];
334             dw[3] |= vf->user_instancing[elem][1];
335          }
336 
337          if (b->vma) {
338             ilo_builder_batch_reloc(builder, pos + 1, b->vma->bo,
339                   b->vma->bo_offset + b->vb[1], 0);
340             ilo_builder_batch_reloc(builder, pos + 2, b->vma->bo,
341                   b->vma->bo_offset + b->vb[2], 0);
342          }
343       }
344 
345       dw += 4;
346       pos += 4;
347    }
348 }
349 
350 /* the user vertex buffer must be uploaded with gen6_user_vertex_buffer() */
351 static inline void
gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder * builder,uint32_t vb_begin,uint32_t vb_end,uint32_t stride)352 gen6_user_3DSTATE_VERTEX_BUFFERS(struct ilo_builder *builder,
353                                  uint32_t vb_begin, uint32_t vb_end,
354                                  uint32_t stride)
355 {
356    const struct ilo_builder_writer *bat =
357       &builder->writers[ILO_BUILDER_WRITER_BATCH];
358    const uint8_t cmd_len = 1 + 4;
359    uint32_t *dw;
360    unsigned pos;
361 
362    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
363 
364    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
365 
366    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_BUFFERS) | (cmd_len - 2);
367    dw++;
368    pos++;
369 
370    /* VERTEX_BUFFER_STATE */
371    dw[0] = 0 << GEN6_VB_DW0_INDEX__SHIFT |
372            GEN6_VB_DW0_ACCESS_VERTEXDATA |
373            stride << GEN6_VB_DW0_PITCH__SHIFT;
374    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
375       dw[0] |= GEN7_VB_DW0_ADDR_MODIFIED;
376 
377    dw[3] = 0;
378 
379    ilo_builder_batch_reloc(builder, pos + 1, bat->bo, vb_begin, 0);
380    ilo_builder_batch_reloc(builder, pos + 2, bat->bo, vb_end, 0);
381 }
382 
383 static inline void
gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder * builder,const struct ilo_state_vf * vf)384 gen6_3DSTATE_VERTEX_ELEMENTS(struct ilo_builder *builder,
385                              const struct ilo_state_vf *vf)
386 {
387    uint8_t cmd_len;
388    uint32_t *dw;
389 
390    ILO_DEV_ASSERT(builder->dev, 6, 8);
391 
392    cmd_len = 1 + 2 * (vf->internal_ve_count + vf->user_ve_count);
393 
394    ilo_builder_batch_pointer(builder, cmd_len, &dw);
395 
396    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VERTEX_ELEMENTS) | (cmd_len - 2);
397    dw++;
398 
399    /*
400     * see vf_params_set_gen6_internal_ve() and
401     * vf_set_gen6_3DSTATE_VERTEX_ELEMENTS()
402     */
403    if (vf->internal_ve_count) {
404       memcpy(dw, vf->internal_ve,
405             sizeof(vf->internal_ve[0]) * vf->internal_ve_count);
406       dw += 2 * vf->internal_ve_count;
407    }
408 
409    memcpy(dw, vf->user_ve, sizeof(vf->user_ve[0]) * vf->user_ve_count);
410 }
411 
412 static inline void
gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder * builder,const struct ilo_state_vf * vf,const struct ilo_state_index_buffer * ib)413 gen6_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
414                           const struct ilo_state_vf *vf,
415                           const struct ilo_state_index_buffer *ib)
416 {
417    const uint8_t cmd_len = 3;
418    uint32_t dw0, *dw;
419    unsigned pos;
420 
421    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
422 
423    dw0 = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2) |
424          builder->mocs << GEN6_IB_DW0_MOCS__SHIFT;
425 
426    /*
427     * see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() and
428     * vf_params_set_gen6_3dstate_index_buffer()
429     */
430    dw0 |= ib->ib[0];
431    if (ilo_dev_gen(builder->dev) <= ILO_GEN(7))
432       dw0 |= vf->cut[0];
433 
434    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
435 
436    dw[0] = dw0;
437    if (ib->vma) {
438       ilo_builder_batch_reloc(builder, pos + 1, ib->vma->bo,
439             ib->vma->bo_offset + ib->ib[1], 0);
440       ilo_builder_batch_reloc(builder, pos + 2, ib->vma->bo,
441             ib->vma->bo_offset + ib->ib[2], 0);
442    } else {
443       dw[1] = 0;
444       dw[2] = 0;
445    }
446 }
447 
448 static inline void
gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder * builder,const struct ilo_state_vf * vf,const struct ilo_state_index_buffer * ib)449 gen8_3DSTATE_INDEX_BUFFER(struct ilo_builder *builder,
450                           const struct ilo_state_vf *vf,
451                           const struct ilo_state_index_buffer *ib)
452 {
453    const uint8_t cmd_len = 5;
454    uint32_t *dw;
455    unsigned pos;
456 
457    ILO_DEV_ASSERT(builder->dev, 8, 8);
458 
459    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
460 
461    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_INDEX_BUFFER) | (cmd_len - 2);
462    /* see index_buffer_set_gen8_3DSTATE_INDEX_BUFFER() */
463    dw[1] = ib->ib[0] |
464            builder->mocs << GEN8_IB_DW1_MOCS__SHIFT;
465 
466    if (ib->vma) {
467       ilo_builder_batch_reloc64(builder, pos + 2, ib->vma->bo,
468             ib->vma->bo_offset + ib->ib[1], 0);
469    } else {
470       dw[2] = 0;
471       dw[3] = 0;
472    }
473 
474    dw[4] = ib->ib[2];
475 }
476 
477 static inline void
gen6_3DSTATE_VS(struct ilo_builder * builder,const struct ilo_state_vs * vs,uint32_t kernel_offset,struct intel_bo * scratch_bo)478 gen6_3DSTATE_VS(struct ilo_builder *builder,
479                 const struct ilo_state_vs *vs,
480                 uint32_t kernel_offset,
481                 struct intel_bo *scratch_bo)
482 {
483    const uint8_t cmd_len = 6;
484    uint32_t *dw;
485    unsigned pos;
486 
487    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
488 
489    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
490 
491    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
492    dw[1] = kernel_offset;
493    /* see vs_set_gen6_3DSTATE_VS() */
494    dw[2] = vs->vs[0];
495    dw[3] = vs->vs[1];
496    dw[4] = vs->vs[2];
497    dw[5] = vs->vs[3];
498 
499    if (ilo_state_vs_get_scratch_size(vs)) {
500       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
501             vs->vs[1], 0);
502    }
503 }
504 
505 static inline void
gen8_3DSTATE_VS(struct ilo_builder * builder,const struct ilo_state_vs * vs,uint32_t kernel_offset,struct intel_bo * scratch_bo)506 gen8_3DSTATE_VS(struct ilo_builder *builder,
507                 const struct ilo_state_vs *vs,
508                 uint32_t kernel_offset,
509                 struct intel_bo *scratch_bo)
510 {
511    const uint8_t cmd_len = 9;
512    uint32_t *dw;
513    unsigned pos;
514 
515    ILO_DEV_ASSERT(builder->dev, 8, 8);
516 
517    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
518 
519    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_VS) | (cmd_len - 2);
520    dw[1] = kernel_offset;
521    dw[2] = 0;
522    /* see vs_set_gen6_3DSTATE_VS() */
523    dw[3] = vs->vs[0];
524    dw[4] = vs->vs[1];
525    dw[5] = 0;
526    dw[6] = vs->vs[2];
527    dw[7] = vs->vs[3];
528    dw[8] = vs->vs[4];
529 
530    if (ilo_state_vs_get_scratch_size(vs)) {
531       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
532             vs->vs[1], 0);
533    }
534 }
535 
536 static inline void
gen7_3DSTATE_HS(struct ilo_builder * builder,const struct ilo_state_hs * hs,uint32_t kernel_offset,struct intel_bo * scratch_bo)537 gen7_3DSTATE_HS(struct ilo_builder *builder,
538                 const struct ilo_state_hs *hs,
539                 uint32_t kernel_offset,
540                 struct intel_bo *scratch_bo)
541 {
542    const uint8_t cmd_len = 7;
543    uint32_t *dw;
544    unsigned pos;
545 
546    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
547 
548    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
549 
550    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
551    /* see hs_set_gen7_3DSTATE_HS() */
552    dw[1] = hs->hs[0];
553    dw[2] = hs->hs[1];
554    dw[3] = kernel_offset;
555    dw[4] = hs->hs[2];
556    dw[5] = hs->hs[3];
557    dw[6] = 0;
558 
559    if (ilo_state_hs_get_scratch_size(hs)) {
560       ilo_builder_batch_reloc(builder, pos + 4, scratch_bo,
561             hs->hs[2], 0);
562    }
563 }
564 
565 static inline void
gen8_3DSTATE_HS(struct ilo_builder * builder,const struct ilo_state_hs * hs,uint32_t kernel_offset,struct intel_bo * scratch_bo)566 gen8_3DSTATE_HS(struct ilo_builder *builder,
567                 const struct ilo_state_hs *hs,
568                 uint32_t kernel_offset,
569                 struct intel_bo *scratch_bo)
570 {
571    const uint8_t cmd_len = 9;
572    uint32_t *dw;
573    unsigned pos;
574 
575    ILO_DEV_ASSERT(builder->dev, 8, 8);
576 
577    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
578 
579    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_HS) | (cmd_len - 2);
580    /* see hs_set_gen7_3DSTATE_HS() */
581    dw[1] = hs->hs[0];
582    dw[2] = hs->hs[1];
583    dw[3] = kernel_offset;
584    dw[4] = 0;
585    dw[5] = hs->hs[2];
586    dw[6] = 0;
587    dw[7] = hs->hs[3];
588    dw[8] = 0;
589 
590    if (ilo_state_hs_get_scratch_size(hs)) {
591       ilo_builder_batch_reloc64(builder, pos + 5, scratch_bo,
592             hs->hs[2], 0);
593    }
594 }
595 
596 static inline void
gen7_3DSTATE_TE(struct ilo_builder * builder,const struct ilo_state_ds * ds)597 gen7_3DSTATE_TE(struct ilo_builder *builder,
598                 const struct ilo_state_ds *ds)
599 {
600    const uint8_t cmd_len = 4;
601    uint32_t *dw;
602 
603    ILO_DEV_ASSERT(builder->dev, 7, 8);
604 
605    ilo_builder_batch_pointer(builder, cmd_len, &dw);
606 
607    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_TE) | (cmd_len - 2);
608    /* see ds_set_gen7_3DSTATE_TE() */
609    dw[1] = ds->te[0];
610    dw[2] = ds->te[1];
611    dw[3] = ds->te[2];
612 }
613 
614 static inline void
gen7_3DSTATE_DS(struct ilo_builder * builder,const struct ilo_state_ds * ds,uint32_t kernel_offset,struct intel_bo * scratch_bo)615 gen7_3DSTATE_DS(struct ilo_builder *builder,
616                 const struct ilo_state_ds *ds,
617                 uint32_t kernel_offset,
618                 struct intel_bo *scratch_bo)
619 {
620    const uint8_t cmd_len = 6;
621    uint32_t *dw;
622    unsigned pos;
623 
624    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
625 
626    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
627 
628    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
629    /* see ds_set_gen7_3DSTATE_DS() */
630    dw[1] = kernel_offset;
631    dw[2] = ds->ds[0];
632    dw[3] = ds->ds[1];
633    dw[4] = ds->ds[2];
634    dw[5] = ds->ds[3];
635 
636    if (ilo_state_ds_get_scratch_size(ds)) {
637       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
638             ds->ds[1], 0);
639    }
640 }
641 
642 static inline void
gen8_3DSTATE_DS(struct ilo_builder * builder,const struct ilo_state_ds * ds,uint32_t kernel_offset,struct intel_bo * scratch_bo)643 gen8_3DSTATE_DS(struct ilo_builder *builder,
644                 const struct ilo_state_ds *ds,
645                 uint32_t kernel_offset,
646                 struct intel_bo *scratch_bo)
647 {
648    const uint8_t cmd_len = 9;
649    uint32_t *dw;
650    unsigned pos;
651 
652    ILO_DEV_ASSERT(builder->dev, 8, 8);
653 
654    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
655 
656    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_DS) | (cmd_len - 2);
657    /* see ds_set_gen7_3DSTATE_DS() */
658    dw[1] = kernel_offset;
659    dw[2] = 0;
660    dw[3] = ds->ds[0];
661    dw[4] = ds->ds[1];
662    dw[5] = 0;
663    dw[6] = ds->ds[2];
664    dw[7] = ds->ds[3];
665    dw[8] = ds->ds[4];
666 
667    if (ilo_state_ds_get_scratch_size(ds)) {
668       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
669             ds->ds[1], 0);
670    }
671 }
672 
673 static inline void
gen6_3DSTATE_GS(struct ilo_builder * builder,const struct ilo_state_gs * gs,uint32_t kernel_offset,struct intel_bo * scratch_bo)674 gen6_3DSTATE_GS(struct ilo_builder *builder,
675                 const struct ilo_state_gs *gs,
676                 uint32_t kernel_offset,
677                 struct intel_bo *scratch_bo)
678 {
679    const uint8_t cmd_len = 7;
680    uint32_t *dw;
681    unsigned pos;
682 
683    ILO_DEV_ASSERT(builder->dev, 6, 6);
684 
685    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
686 
687    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
688    dw[1] = kernel_offset;
689    /* see gs_set_gen6_3DSTATE_GS() */
690    dw[2] = gs->gs[0];
691    dw[3] = gs->gs[1];
692    dw[4] = gs->gs[2];
693    dw[5] = gs->gs[3];
694    dw[6] = gs->gs[4];
695 
696    if (ilo_state_gs_get_scratch_size(gs)) {
697       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
698             gs->gs[1], 0);
699    }
700 }
701 
702 static inline void
gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder * builder,int index,unsigned svbi,unsigned max_svbi,bool load_vertex_count)703 gen6_3DSTATE_GS_SVB_INDEX(struct ilo_builder *builder,
704                           int index, unsigned svbi,
705                           unsigned max_svbi,
706                           bool load_vertex_count)
707 {
708    const uint8_t cmd_len = 4;
709    uint32_t *dw;
710 
711    ILO_DEV_ASSERT(builder->dev, 6, 6);
712    assert(index >= 0 && index < 4);
713 
714    ilo_builder_batch_pointer(builder, cmd_len, &dw);
715 
716    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS_SVB_INDEX) | (cmd_len - 2);
717 
718    dw[1] = index << GEN6_SVBI_DW1_INDEX__SHIFT;
719    if (load_vertex_count)
720       dw[1] |= GEN6_SVBI_DW1_LOAD_INTERNAL_VERTEX_COUNT;
721 
722    dw[2] = svbi;
723    dw[3] = max_svbi;
724 }
725 
726 static inline void
gen7_3DSTATE_GS(struct ilo_builder * builder,const struct ilo_state_gs * gs,uint32_t kernel_offset,struct intel_bo * scratch_bo)727 gen7_3DSTATE_GS(struct ilo_builder *builder,
728                 const struct ilo_state_gs *gs,
729                 uint32_t kernel_offset,
730                 struct intel_bo *scratch_bo)
731 {
732    const uint8_t cmd_len = 7;
733    uint32_t *dw;
734    unsigned pos;
735 
736    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
737 
738    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
739 
740    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
741    dw[1] = kernel_offset;
742    /* see gs_set_gen7_3DSTATE_GS() */
743    dw[2] = gs->gs[0];
744    dw[3] = gs->gs[1];
745    dw[4] = gs->gs[2];
746    dw[5] = gs->gs[3];
747    dw[6] = 0;
748 
749    if (ilo_state_gs_get_scratch_size(gs)) {
750       ilo_builder_batch_reloc(builder, pos + 3, scratch_bo,
751             gs->gs[1], 0);
752    }
753 }
754 
755 static inline void
gen8_3DSTATE_GS(struct ilo_builder * builder,const struct ilo_state_gs * gs,uint32_t kernel_offset,struct intel_bo * scratch_bo)756 gen8_3DSTATE_GS(struct ilo_builder *builder,
757                 const struct ilo_state_gs *gs,
758                 uint32_t kernel_offset,
759                 struct intel_bo *scratch_bo)
760 {
761    const uint8_t cmd_len = 10;
762    uint32_t *dw;
763    unsigned pos;
764 
765    ILO_DEV_ASSERT(builder->dev, 8, 8);
766 
767    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
768 
769    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_GS) | (cmd_len - 2);
770    dw[1] = kernel_offset;
771    dw[2] = 0;
772    /* see gs_set_gen7_3DSTATE_GS() */
773    dw[3] = gs->gs[0];
774    dw[4] = gs->gs[1];
775    dw[5] = 0;
776    dw[6] = gs->gs[2];
777    dw[7] = gs->gs[3];
778    dw[8] = 0;
779    dw[9] = gs->gs[4];
780 
781    if (ilo_state_gs_get_scratch_size(gs)) {
782       ilo_builder_batch_reloc64(builder, pos + 4, scratch_bo,
783             gs->gs[1], 0);
784    }
785 }
786 
787 static inline void
gen7_3DSTATE_STREAMOUT(struct ilo_builder * builder,const struct ilo_state_sol * sol)788 gen7_3DSTATE_STREAMOUT(struct ilo_builder *builder,
789                        const struct ilo_state_sol *sol)
790 {
791    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 5 : 3;
792    uint32_t *dw;
793 
794    ILO_DEV_ASSERT(builder->dev, 7, 8);
795 
796    ilo_builder_batch_pointer(builder, cmd_len, &dw);
797 
798    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_STREAMOUT) | (cmd_len - 2);
799    /* see sol_set_gen7_3DSTATE_STREAMOUT() */
800    dw[1] = sol->streamout[0];
801    dw[2] = sol->streamout[1];
802    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
803       dw[3] = sol->strides[1] << GEN8_SO_DW3_BUFFER1_PITCH__SHIFT |
804               sol->strides[0] << GEN8_SO_DW3_BUFFER0_PITCH__SHIFT;
805       dw[4] = sol->strides[3] << GEN8_SO_DW4_BUFFER3_PITCH__SHIFT |
806               sol->strides[2] << GEN8_SO_DW4_BUFFER2_PITCH__SHIFT;
807    }
808 }
809 
810 static inline void
gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder * builder,const struct ilo_state_sol * sol)811 gen7_3DSTATE_SO_DECL_LIST(struct ilo_builder *builder,
812                           const struct ilo_state_sol *sol)
813 {
814    /*
815     * Note that "DWord Length" has 9 bits for this command and the type of
816     * cmd_len cannot be uint8_t.
817     */
818    uint16_t cmd_len;
819    int cmd_decl_count;
820    uint32_t *dw;
821 
822    ILO_DEV_ASSERT(builder->dev, 7, 8);
823 
824    if (ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) {
825       cmd_decl_count = sol->decl_count;
826    } else {
827       /*
828        * From the Ivy Bridge PRM, volume 2 part 1, page 201:
829        *
830        *     "Errata: All 128 decls for all four streams must be included
831        *      whenever this command is issued. The "Num Entries [n]" fields
832        *      still contain the actual numbers of valid decls."
833        */
834       cmd_decl_count = 128;
835    }
836 
837    cmd_len = 3 + 2 * cmd_decl_count;
838 
839    ilo_builder_batch_pointer(builder, cmd_len, &dw);
840 
841    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_DECL_LIST) | (cmd_len - 2);
842    /* see sol_set_gen7_3DSTATE_SO_DECL_LIST() */
843    dw[1] = sol->so_decl[0];
844    dw[2] = sol->so_decl[1];
845    memcpy(&dw[3], sol->decl, sizeof(sol->decl[0]) * sol->decl_count);
846 
847    if (sol->decl_count < cmd_decl_count) {
848       memset(&dw[3 + 2 * sol->decl_count], 0, sizeof(sol->decl[0]) *
849             cmd_decl_count - sol->decl_count);
850    }
851 }
852 
853 static inline void
gen7_3DSTATE_SO_BUFFER(struct ilo_builder * builder,const struct ilo_state_sol * sol,const struct ilo_state_sol_buffer * sb,uint8_t buffer)854 gen7_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
855                        const struct ilo_state_sol *sol,
856                        const struct ilo_state_sol_buffer *sb,
857                        uint8_t buffer)
858 {
859    const uint8_t cmd_len = 4;
860    uint32_t *dw;
861    unsigned pos;
862 
863    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
864 
865    assert(buffer < ILO_STATE_SOL_MAX_BUFFER_COUNT);
866 
867    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
868 
869    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
870    /* see sol_buffer_set_gen7_3dstate_so_buffer() */
871    dw[1] = buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
872            builder->mocs << GEN7_SO_BUF_DW1_MOCS__SHIFT |
873            sol->strides[buffer] << GEN7_SO_BUF_DW1_PITCH__SHIFT;
874 
875    if (sb->vma) {
876       ilo_builder_batch_reloc(builder, pos + 2, sb->vma->bo,
877             sb->vma->bo_offset + sb->so_buf[0], INTEL_RELOC_WRITE);
878       ilo_builder_batch_reloc(builder, pos + 3, sb->vma->bo,
879             sb->vma->bo_offset + sb->so_buf[1], INTEL_RELOC_WRITE);
880    } else {
881       dw[2] = 0;
882       dw[3] = 0;
883    }
884 }
885 
886 static inline void
gen8_3DSTATE_SO_BUFFER(struct ilo_builder * builder,const struct ilo_state_sol * sol,const struct ilo_state_sol_buffer * sb,uint8_t buffer)887 gen8_3DSTATE_SO_BUFFER(struct ilo_builder *builder,
888                        const struct ilo_state_sol *sol,
889                        const struct ilo_state_sol_buffer *sb,
890                        uint8_t buffer)
891 {
892    const uint8_t cmd_len = 8;
893    uint32_t *dw;
894    unsigned pos;
895 
896    ILO_DEV_ASSERT(builder->dev, 8, 8);
897 
898    pos = ilo_builder_batch_pointer(builder, cmd_len, &dw);
899 
900    dw[0] = GEN7_RENDER_CMD(3D, 3DSTATE_SO_BUFFER) | (cmd_len - 2);
901    /* see sol_buffer_set_gen8_3dstate_so_buffer() */
902    dw[1] = sb->so_buf[0] |
903            buffer << GEN7_SO_BUF_DW1_INDEX__SHIFT |
904            builder->mocs << GEN8_SO_BUF_DW1_MOCS__SHIFT;
905 
906    if (sb->vma) {
907       ilo_builder_batch_reloc64(builder, pos + 2, sb->vma->bo,
908             sb->vma->bo_offset + sb->so_buf[1], INTEL_RELOC_WRITE);
909    } else {
910       dw[2] = 0;
911       dw[3] = 0;
912    }
913 
914    dw[4] = sb->so_buf[2];
915 
916    if (sb->write_offset_vma) {
917       ilo_builder_batch_reloc64(builder, pos + 5, sb->write_offset_vma->bo,
918             sb->write_offset_vma->bo_offset + sizeof(uint32_t) * buffer,
919             INTEL_RELOC_WRITE);
920    } else {
921       dw[5] = 0;
922       dw[6] = 0;
923    }
924 
925    dw[7] = sb->so_buf[3];
926 }
927 
928 static inline void
gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder * builder,uint32_t vs_binding_table,uint32_t gs_binding_table,uint32_t ps_binding_table)929 gen6_3DSTATE_BINDING_TABLE_POINTERS(struct ilo_builder *builder,
930                                     uint32_t vs_binding_table,
931                                     uint32_t gs_binding_table,
932                                     uint32_t ps_binding_table)
933 {
934    const uint8_t cmd_len = 4;
935    uint32_t *dw;
936 
937    ILO_DEV_ASSERT(builder->dev, 6, 6);
938 
939    ilo_builder_batch_pointer(builder, cmd_len, &dw);
940 
941    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_BINDING_TABLE_POINTERS) |
942            GEN6_BINDING_TABLE_PTR_DW0_VS_CHANGED |
943            GEN6_BINDING_TABLE_PTR_DW0_GS_CHANGED |
944            GEN6_BINDING_TABLE_PTR_DW0_PS_CHANGED |
945            (cmd_len - 2);
946    dw[1] = vs_binding_table;
947    dw[2] = gs_binding_table;
948    dw[3] = ps_binding_table;
949 }
950 
951 static inline void
gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder * builder,uint32_t vs_sampler_state,uint32_t gs_sampler_state,uint32_t ps_sampler_state)952 gen6_3DSTATE_SAMPLER_STATE_POINTERS(struct ilo_builder *builder,
953                                     uint32_t vs_sampler_state,
954                                     uint32_t gs_sampler_state,
955                                     uint32_t ps_sampler_state)
956 {
957    const uint8_t cmd_len = 4;
958    uint32_t *dw;
959 
960    ILO_DEV_ASSERT(builder->dev, 6, 6);
961 
962    ilo_builder_batch_pointer(builder, cmd_len, &dw);
963 
964    dw[0] = GEN6_RENDER_CMD(3D, 3DSTATE_SAMPLER_STATE_POINTERS) |
965            GEN6_SAMPLER_PTR_DW0_VS_CHANGED |
966            GEN6_SAMPLER_PTR_DW0_GS_CHANGED |
967            GEN6_SAMPLER_PTR_DW0_PS_CHANGED |
968            (cmd_len - 2);
969    dw[1] = vs_sampler_state;
970    dw[2] = gs_sampler_state;
971    dw[3] = ps_sampler_state;
972 }
973 
974 static inline void
gen7_3dstate_pointer(struct ilo_builder * builder,int subop,uint32_t pointer)975 gen7_3dstate_pointer(struct ilo_builder *builder,
976                      int subop, uint32_t pointer)
977 {
978    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
979                         GEN6_RENDER_SUBTYPE_3D |
980                         subop;
981    const uint8_t cmd_len = 2;
982    uint32_t *dw;
983 
984    ILO_DEV_ASSERT(builder->dev, 7, 8);
985 
986    ilo_builder_batch_pointer(builder, cmd_len, &dw);
987 
988    dw[0] = cmd | (cmd_len - 2);
989    dw[1] = pointer;
990 }
991 
992 static inline void
gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder * builder,uint32_t binding_table)993 gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(struct ilo_builder *builder,
994                                        uint32_t binding_table)
995 {
996    gen7_3dstate_pointer(builder,
997          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_VS,
998          binding_table);
999 }
1000 
1001 static inline void
gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder * builder,uint32_t binding_table)1002 gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(struct ilo_builder *builder,
1003                                        uint32_t binding_table)
1004 {
1005    gen7_3dstate_pointer(builder,
1006          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_HS,
1007          binding_table);
1008 }
1009 
1010 static inline void
gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder * builder,uint32_t binding_table)1011 gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(struct ilo_builder *builder,
1012                                        uint32_t binding_table)
1013 {
1014    gen7_3dstate_pointer(builder,
1015          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_DS,
1016          binding_table);
1017 }
1018 
1019 static inline void
gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder * builder,uint32_t binding_table)1020 gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(struct ilo_builder *builder,
1021                                        uint32_t binding_table)
1022 {
1023    gen7_3dstate_pointer(builder,
1024          GEN7_RENDER_OPCODE_3DSTATE_BINDING_TABLE_POINTERS_GS,
1025          binding_table);
1026 }
1027 
1028 static inline void
gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder * builder,uint32_t sampler_state)1029 gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(struct ilo_builder *builder,
1030                                        uint32_t sampler_state)
1031 {
1032    gen7_3dstate_pointer(builder,
1033          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_VS,
1034          sampler_state);
1035 }
1036 
1037 static inline void
gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder * builder,uint32_t sampler_state)1038 gen7_3DSTATE_SAMPLER_STATE_POINTERS_HS(struct ilo_builder *builder,
1039                                        uint32_t sampler_state)
1040 {
1041    gen7_3dstate_pointer(builder,
1042          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_HS,
1043          sampler_state);
1044 }
1045 
1046 static inline void
gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder * builder,uint32_t sampler_state)1047 gen7_3DSTATE_SAMPLER_STATE_POINTERS_DS(struct ilo_builder *builder,
1048                                        uint32_t sampler_state)
1049 {
1050    gen7_3dstate_pointer(builder,
1051          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_DS,
1052          sampler_state);
1053 }
1054 
1055 static inline void
gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder * builder,uint32_t sampler_state)1056 gen7_3DSTATE_SAMPLER_STATE_POINTERS_GS(struct ilo_builder *builder,
1057                                        uint32_t sampler_state)
1058 {
1059    gen7_3dstate_pointer(builder,
1060          GEN7_RENDER_OPCODE_3DSTATE_SAMPLER_STATE_POINTERS_GS,
1061          sampler_state);
1062 }
1063 
1064 static inline void
gen6_3dstate_constant(struct ilo_builder * builder,int subop,const uint32_t * bufs,const int * sizes,int num_bufs)1065 gen6_3dstate_constant(struct ilo_builder *builder, int subop,
1066                       const uint32_t *bufs, const int *sizes,
1067                       int num_bufs)
1068 {
1069    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1070                         GEN6_RENDER_SUBTYPE_3D |
1071                         subop;
1072    const uint8_t cmd_len = 5;
1073    unsigned buf_enabled = 0x0;
1074    uint32_t buf_dw[4], *dw;
1075    int max_read_length, total_read_length;
1076    int i;
1077 
1078    ILO_DEV_ASSERT(builder->dev, 6, 6);
1079 
1080    assert(num_bufs <= 4);
1081 
1082    /*
1083     * From the Sandy Bridge PRM, volume 2 part 1, page 138:
1084     *
1085     *     "(3DSTATE_CONSTANT_VS) The sum of all four read length fields (each
1086     *      incremented to represent the actual read length) must be less than
1087     *      or equal to 32"
1088     *
1089     * From the Sandy Bridge PRM, volume 2 part 1, page 161:
1090     *
1091     *     "(3DSTATE_CONSTANT_GS) The sum of all four read length fields (each
1092     *      incremented to represent the actual read length) must be less than
1093     *      or equal to 64"
1094     *
1095     * From the Sandy Bridge PRM, volume 2 part 1, page 287:
1096     *
1097     *     "(3DSTATE_CONSTANT_PS) The sum of all four read length fields (each
1098     *      incremented to represent the actual read length) must be less than
1099     *      or equal to 64"
1100     */
1101    switch (subop) {
1102    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS:
1103       max_read_length = 32;
1104       break;
1105    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS:
1106    case GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_PS:
1107       max_read_length = 64;
1108       break;
1109    default:
1110       assert(!"unknown pcb subop");
1111       max_read_length = 0;
1112       break;
1113    }
1114 
1115    total_read_length = 0;
1116    for (i = 0; i < 4; i++) {
1117       if (i < num_bufs && sizes[i]) {
1118          /* in 256-bit units */
1119          const int read_len = (sizes[i] + 31) / 32;
1120 
1121          assert(bufs[i] % 32 == 0);
1122          assert(read_len <= 32);
1123 
1124          buf_enabled |= 1 << i;
1125          buf_dw[i] = bufs[i] | (read_len - 1);
1126 
1127          total_read_length += read_len;
1128       } else {
1129          buf_dw[i] = 0;
1130       }
1131    }
1132 
1133    assert(total_read_length <= max_read_length);
1134 
1135    ilo_builder_batch_pointer(builder, cmd_len, &dw);
1136 
1137    dw[0] = cmd | (cmd_len - 2) |
1138            buf_enabled << GEN6_CONSTANT_DW0_BUFFER_ENABLES__SHIFT |
1139            builder->mocs << GEN6_CONSTANT_DW0_MOCS__SHIFT;
1140 
1141    memcpy(&dw[1], buf_dw, sizeof(buf_dw));
1142 }
1143 
1144 static inline void
gen6_3DSTATE_CONSTANT_VS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1145 gen6_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1146                          const uint32_t *bufs, const int *sizes,
1147                          int num_bufs)
1148 {
1149    gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1150          bufs, sizes, num_bufs);
1151 }
1152 
1153 static inline void
gen6_3DSTATE_CONSTANT_GS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1154 gen6_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1155                          const uint32_t *bufs, const int *sizes,
1156                          int num_bufs)
1157 {
1158    gen6_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1159          bufs, sizes, num_bufs);
1160 }
1161 
1162 static inline void
gen7_3dstate_constant(struct ilo_builder * builder,int subop,const uint32_t * bufs,const int * sizes,int num_bufs)1163 gen7_3dstate_constant(struct ilo_builder *builder,
1164                       int subop,
1165                       const uint32_t *bufs, const int *sizes,
1166                       int num_bufs)
1167 {
1168    const uint32_t cmd = GEN6_RENDER_TYPE_RENDER |
1169                         GEN6_RENDER_SUBTYPE_3D |
1170                         subop;
1171    const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 11 : 7;
1172    uint32_t payload[6], *dw;
1173    int total_read_length, i;
1174 
1175    ILO_DEV_ASSERT(builder->dev, 7, 8);
1176 
1177    /* VS, HS, DS, GS, and PS variants */
1178    assert(subop >= GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS &&
1179           subop <= GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS &&
1180           subop != GEN6_RENDER_OPCODE_3DSTATE_SAMPLE_MASK);
1181 
1182    assert(num_bufs <= 4);
1183 
1184    payload[0] = 0;
1185    payload[1] = 0;
1186 
1187    total_read_length = 0;
1188    for (i = 0; i < 4; i++) {
1189       int read_len;
1190 
1191       /*
1192        * From the Ivy Bridge PRM, volume 2 part 1, page 112:
1193        *
1194        *     "Constant buffers must be enabled in order from Constant Buffer 0
1195        *      to Constant Buffer 3 within this command.  For example, it is
1196        *      not allowed to enable Constant Buffer 1 by programming a
1197        *      non-zero value in the VS Constant Buffer 1 Read Length without a
1198        *      non-zero value in VS Constant Buffer 0 Read Length."
1199        */
1200       if (i >= num_bufs || !sizes[i]) {
1201          for (; i < 4; i++) {
1202             assert(i >= num_bufs || !sizes[i]);
1203             payload[2 + i] = 0;
1204          }
1205          break;
1206       }
1207 
1208       /* read lengths are in 256-bit units */
1209       read_len = (sizes[i] + 31) / 32;
1210       /* the lower 5 bits are used for memory object control state */
1211       assert(bufs[i] % 32 == 0);
1212 
1213       payload[i / 2] |= read_len << ((i % 2) ? 16 : 0);
1214       payload[2 + i] = bufs[i];
1215 
1216       total_read_length += read_len;
1217    }
1218 
1219    /*
1220     * From the Ivy Bridge PRM, volume 2 part 1, page 113:
1221     *
1222     *     "The sum of all four read length fields must be less than or equal
1223     *      to the size of 64"
1224     */
1225    assert(total_read_length <= 64);
1226 
1227    ilo_builder_batch_pointer(builder, cmd_len, &dw);
1228 
1229    dw[0] = cmd | (cmd_len - 2);
1230    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1231       dw[1] = payload[0];
1232       dw[2] = payload[1];
1233       dw[3] = payload[2];
1234       dw[4] = 0;
1235       dw[5] = payload[3];
1236       dw[6] = 0;
1237       dw[7] = payload[4];
1238       dw[8] = 0;
1239       dw[9] = payload[5];
1240       dw[10] = 0;
1241    } else {
1242       payload[2] |= builder->mocs << GEN7_CONSTANT_DW_ADDR_MOCS__SHIFT;
1243 
1244       memcpy(&dw[1], payload, sizeof(payload));
1245    }
1246 }
1247 
1248 static inline void
gen7_3DSTATE_CONSTANT_VS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1249 gen7_3DSTATE_CONSTANT_VS(struct ilo_builder *builder,
1250                          const uint32_t *bufs, const int *sizes,
1251                          int num_bufs)
1252 {
1253    gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_VS,
1254          bufs, sizes, num_bufs);
1255 }
1256 
1257 static inline void
gen7_3DSTATE_CONSTANT_HS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1258 gen7_3DSTATE_CONSTANT_HS(struct ilo_builder *builder,
1259                          const uint32_t *bufs, const int *sizes,
1260                          int num_bufs)
1261 {
1262    gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_HS,
1263          bufs, sizes, num_bufs);
1264 }
1265 
1266 static inline void
gen7_3DSTATE_CONSTANT_DS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1267 gen7_3DSTATE_CONSTANT_DS(struct ilo_builder *builder,
1268                          const uint32_t *bufs, const int *sizes,
1269                          int num_bufs)
1270 {
1271    gen7_3dstate_constant(builder, GEN7_RENDER_OPCODE_3DSTATE_CONSTANT_DS,
1272          bufs, sizes, num_bufs);
1273 }
1274 
1275 static inline void
gen7_3DSTATE_CONSTANT_GS(struct ilo_builder * builder,const uint32_t * bufs,const int * sizes,int num_bufs)1276 gen7_3DSTATE_CONSTANT_GS(struct ilo_builder *builder,
1277                          const uint32_t *bufs, const int *sizes,
1278                          int num_bufs)
1279 {
1280    gen7_3dstate_constant(builder, GEN6_RENDER_OPCODE_3DSTATE_CONSTANT_GS,
1281          bufs, sizes, num_bufs);
1282 }
1283 
1284 static inline uint32_t
gen6_BINDING_TABLE_STATE(struct ilo_builder * builder,const uint32_t * surface_states,int num_surface_states)1285 gen6_BINDING_TABLE_STATE(struct ilo_builder *builder,
1286                          const uint32_t *surface_states,
1287                          int num_surface_states)
1288 {
1289    const int state_align = 32;
1290    const int state_len = num_surface_states;
1291    uint32_t state_offset, *dw;
1292 
1293    ILO_DEV_ASSERT(builder->dev, 6, 8);
1294 
1295    /*
1296     * From the Sandy Bridge PRM, volume 4 part 1, page 69:
1297     *
1298     *     "It is stored as an array of up to 256 elements..."
1299     */
1300    assert(num_surface_states <= 256);
1301 
1302    if (!num_surface_states)
1303       return 0;
1304 
1305    state_offset = ilo_builder_surface_pointer(builder,
1306          ILO_BUILDER_ITEM_BINDING_TABLE, state_align, state_len, &dw);
1307    memcpy(dw, surface_states, state_len << 2);
1308 
1309    return state_offset;
1310 }
1311 
1312 static inline uint32_t
gen6_SURFACE_STATE(struct ilo_builder * builder,const struct ilo_state_surface * surf)1313 gen6_SURFACE_STATE(struct ilo_builder *builder,
1314                    const struct ilo_state_surface *surf)
1315 {
1316    int state_align, state_len;
1317    uint32_t state_offset, *dw;
1318 
1319    ILO_DEV_ASSERT(builder->dev, 6, 8);
1320 
1321    if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
1322       state_align = 64;
1323       state_len = 13;
1324 
1325       state_offset = ilo_builder_surface_pointer(builder,
1326             ILO_BUILDER_ITEM_SURFACE, state_align, state_len, &dw);
1327       memcpy(dw, surf->surface, state_len << 2);
1328 
1329       if (surf->vma) {
1330          const uint32_t mocs = (surf->scanout) ?
1331             (GEN8_MOCS_MT_PTE | GEN8_MOCS_CT_L3) : builder->mocs;
1332 
1333          dw[1] |= mocs << GEN8_SURFACE_DW1_MOCS__SHIFT;
1334 
1335          ilo_builder_surface_reloc64(builder, state_offset, 8, surf->vma->bo,
1336                surf->vma->bo_offset + surf->surface[8],
1337                (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->vma) {
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->vma->bo,
1355                surf->vma->bo_offset + surf->surface[1],
1356                (surf->readonly) ? 0 : INTEL_RELOC_WRITE);
1357       }
1358    }
1359 
1360    return state_offset;
1361 }
1362 
1363 static inline uint32_t
gen6_SAMPLER_STATE(struct ilo_builder * builder,const struct ilo_state_sampler * samplers,const uint32_t * sampler_border_colors,int sampler_count)1364 gen6_SAMPLER_STATE(struct ilo_builder *builder,
1365                    const struct ilo_state_sampler *samplers,
1366                    const uint32_t *sampler_border_colors,
1367                    int sampler_count)
1368 {
1369    const int state_align = 32;
1370    const int state_len = 4 * sampler_count;
1371    uint32_t state_offset, *dw;
1372    int i;
1373 
1374    ILO_DEV_ASSERT(builder->dev, 6, 8);
1375 
1376    /*
1377     * From the Sandy Bridge PRM, volume 4 part 1, page 101:
1378     *
1379     *     "The sampler state is stored as an array of up to 16 elements..."
1380     */
1381    assert(sampler_count <= 16);
1382 
1383    if (!sampler_count)
1384       return 0;
1385 
1386    /*
1387     * From the Sandy Bridge PRM, volume 2 part 1, page 132:
1388     *
1389     *     "(Sampler Count of 3DSTATE_VS) Specifies how many samplers (in
1390     *      multiples of 4) the vertex shader 0 kernel uses. Used only for
1391     *      prefetching the associated sampler state entries.
1392     *
1393     * It also applies to other shader stages.
1394     */
1395    ilo_builder_dynamic_pad_top(builder, 4 * (4 - (sampler_count % 4)));
1396 
1397    state_offset = ilo_builder_dynamic_pointer(builder,
1398          ILO_BUILDER_ITEM_SAMPLER, state_align, state_len, &dw);
1399 
1400    for (i = 0; i < sampler_count; i++) {
1401       /* see sampler_set_gen6_SAMPLER_STATE() */
1402       dw[0] = samplers[i].sampler[0];
1403       dw[1] = samplers[i].sampler[1];
1404       dw[3] = samplers[i].sampler[2];
1405 
1406       assert(!(sampler_border_colors[i] & 0x1f));
1407       dw[2] = sampler_border_colors[i];
1408 
1409       dw += 4;
1410    }
1411 
1412    return state_offset;
1413 }
1414 
1415 static inline uint32_t
gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder * builder,const struct ilo_state_sampler_border * border)1416 gen6_SAMPLER_BORDER_COLOR_STATE(struct ilo_builder *builder,
1417                                 const struct ilo_state_sampler_border *border)
1418 {
1419    const int state_align =
1420       (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) ? 64 : 32;
1421    const int state_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 12;
1422 
1423    ILO_DEV_ASSERT(builder->dev, 6, 8);
1424 
1425    /*
1426     * see border_set_gen6_SAMPLER_BORDER_COLOR_STATE() and
1427     * border_set_gen7_SAMPLER_BORDER_COLOR_STATE()
1428     */
1429    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1430          state_align, state_len, border->color);
1431 }
1432 
1433 static inline uint32_t
gen6_push_constant_buffer(struct ilo_builder * builder,int size,void ** pcb)1434 gen6_push_constant_buffer(struct ilo_builder *builder,
1435                           int size, void **pcb)
1436 {
1437    /*
1438     * For all VS, GS, FS, and CS push constant buffers, they must be aligned
1439     * to 32 bytes, and their sizes are specified in 256-bit units.
1440     */
1441    const int state_align = 32;
1442    const int state_len = align(size, 32) / 4;
1443    uint32_t state_offset;
1444    char *buf;
1445 
1446    ILO_DEV_ASSERT(builder->dev, 6, 8);
1447 
1448    state_offset = ilo_builder_dynamic_pointer(builder,
1449          ILO_BUILDER_ITEM_BLOB, state_align, state_len, (uint32_t **) &buf);
1450 
1451    /* zero out the unused range */
1452    if (size < state_len * 4)
1453       memset(&buf[size], 0, state_len * 4 - size);
1454 
1455    if (pcb)
1456       *pcb = buf;
1457 
1458    return state_offset;
1459 }
1460 
1461 static inline uint32_t
gen6_user_vertex_buffer(struct ilo_builder * builder,int size,const void * vertices)1462 gen6_user_vertex_buffer(struct ilo_builder *builder,
1463                         int size, const void *vertices)
1464 {
1465    const int state_align = 8;
1466    const int state_len = size / 4;
1467 
1468    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
1469 
1470    assert(size % 4 == 0);
1471 
1472    return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLOB,
1473          state_align, state_len, vertices);
1474 }
1475 
1476 #endif /* ILO_BUILDER_3D_TOP_H */
1477