1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2012-2015 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#include "ilo_debug.h"
29#include "ilo_state_urb.h"
30
31struct urb_configuration {
32   uint8_t vs_pcb_alloc_kb;
33   uint8_t hs_pcb_alloc_kb;
34   uint8_t ds_pcb_alloc_kb;
35   uint8_t gs_pcb_alloc_kb;
36   uint8_t ps_pcb_alloc_kb;
37
38   uint8_t urb_offset_8kb;
39
40   uint8_t vs_urb_alloc_8kb;
41   uint8_t hs_urb_alloc_8kb;
42   uint8_t ds_urb_alloc_8kb;
43   uint8_t gs_urb_alloc_8kb;
44
45   uint8_t vs_entry_rows;
46   uint8_t hs_entry_rows;
47   uint8_t ds_entry_rows;
48   uint8_t gs_entry_rows;
49
50   int vs_entry_count;
51   int hs_entry_count;
52   int ds_entry_count;
53   int gs_entry_count;
54};
55
56static void
57urb_alloc_gen7_pcb(const struct ilo_dev *dev,
58                   const struct ilo_state_urb_info *info,
59                   struct urb_configuration *conf)
60{
61   /*
62    * From the Haswell PRM, volume 2b, page 940:
63    *
64    *     "[0,16] (0KB - 16KB) Increments of 1KB DevHSW:GT1, DevHSW:GT2
65    *      [0,32] (0KB - 32KB) Increments of 2KB DevHSW:GT3"
66    */
67   const uint8_t increment_kb =
68      (ilo_dev_gen(dev) >= ILO_GEN(8) ||
69       (ilo_dev_gen(dev) == ILO_GEN(7.5) && dev->gt == 3)) ? 2 : 1;
70
71   ILO_DEV_ASSERT(dev, 7, 8);
72
73   /*
74    * Keep the strategy simple as we do not know the workloads and how
75    * expensive it is to change the configuration frequently.
76    */
77   if (info->hs_const_data || info->ds_const_data) {
78      conf->vs_pcb_alloc_kb = increment_kb * 4;
79      conf->hs_pcb_alloc_kb = increment_kb * 3;
80      conf->ds_pcb_alloc_kb = increment_kb * 3;
81      conf->gs_pcb_alloc_kb = increment_kb * 3;
82      conf->ps_pcb_alloc_kb = increment_kb * 3;
83   } else if (info->gs_const_data) {
84      conf->vs_pcb_alloc_kb = increment_kb * 6;
85      conf->gs_pcb_alloc_kb = increment_kb * 5;
86      conf->ps_pcb_alloc_kb = increment_kb * 5;
87   } else {
88      conf->vs_pcb_alloc_kb = increment_kb * 8;
89      conf->ps_pcb_alloc_kb = increment_kb * 8;
90   }
91
92   conf->urb_offset_8kb = increment_kb * 16 / 8;
93}
94
95static void
96urb_alloc_gen6_urb(const struct ilo_dev *dev,
97                   const struct ilo_state_urb_info *info,
98                   struct urb_configuration *conf)
99{
100   /*
101    * From the Ivy Bridge PRM, volume 2 part 1, page 34:
102    *
103    *     "(VS URB Starting Address) Offset from the start of the URB memory
104    *      where VS starts its allocation, specified in multiples of 8 KB."
105    *
106    * Same for other stages.
107    */
108   const int space_avail_8kb = dev->urb_size / 8192 - conf->urb_offset_8kb;
109
110   /*
111    * From the Sandy Bridge PRM, volume 2 part 1, page 173:
112    *
113    *     "Programming Note: If the GS stage is enabled, software must always
114    *      allocate at least one GS URB Entry. This is true even if the GS
115    *      thread never needs to output vertices to the urb, e.g., when only
116    *      performing stream output. This is an artifact of the need to pass
117    *      the GS thread an initial destination URB handle."
118    */
119   const bool force_gs_alloc =
120      (ilo_dev_gen(dev) == ILO_GEN(6) && info->gs_enable);
121
122   ILO_DEV_ASSERT(dev, 6, 8);
123
124   if (info->hs_entry_size || info->ds_entry_size) {
125      conf->vs_urb_alloc_8kb = space_avail_8kb / 4;
126      conf->hs_urb_alloc_8kb = space_avail_8kb / 4;
127      conf->ds_urb_alloc_8kb = space_avail_8kb / 4;
128      conf->gs_urb_alloc_8kb = space_avail_8kb / 4;
129
130      if (space_avail_8kb % 4) {
131         assert(space_avail_8kb % 2 == 0);
132         conf->vs_urb_alloc_8kb++;
133         conf->gs_urb_alloc_8kb++;
134      }
135   } else if (info->gs_entry_size || force_gs_alloc) {
136      assert(space_avail_8kb % 2 == 0);
137      conf->vs_urb_alloc_8kb = space_avail_8kb / 2;
138      conf->gs_urb_alloc_8kb = space_avail_8kb / 2;
139   } else {
140      conf->vs_urb_alloc_8kb = space_avail_8kb;
141   }
142}
143
144static bool
145urb_init_gen6_vs_entry(const struct ilo_dev *dev,
146                       const struct ilo_state_urb_info *info,
147                       struct urb_configuration *conf)
148{
149   /*
150    * From the Sandy Bridge PRM, volume 2 part 1, page 28:
151    *
152    *     "(VS URB Entry Allocation Size)
153    *      Range [0,4] = [1,5] 1024-bit URB rows"
154    *
155    *     "(VS Number of URB Entries)
156    *      Range [24,256] in multiples of 4
157    *            [24, 128] in multiples of 4[DevSNBGT1]"
158    */
159   const int max_entry_count = (dev->gt == 2) ? 256 : 252;
160   const int row_size = 1024 / 8;
161   int row_count, entry_count;
162   int entry_size;
163
164   ILO_DEV_ASSERT(dev, 6, 6);
165
166   /* VE and VS share the same VUE for each vertex */
167   entry_size = info->vs_entry_size;
168   if (entry_size < info->ve_entry_size)
169      entry_size = info->ve_entry_size;
170
171   row_count = (entry_size + row_size - 1) / row_size;
172   if (row_count > 5)
173      return false;
174   else if (!row_count)
175      row_count++;
176
177   entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count);
178   if (entry_count > max_entry_count)
179      entry_count = max_entry_count;
180   entry_count &= ~3;
181   assert(entry_count >= 24);
182
183   conf->vs_entry_rows = row_count;
184   conf->vs_entry_count = entry_count;
185
186   return true;
187}
188
189static bool
190urb_init_gen6_gs_entry(const struct ilo_dev *dev,
191                       const struct ilo_state_urb_info *info,
192                       struct urb_configuration *conf)
193{
194   /*
195    * From the Sandy Bridge PRM, volume 2 part 1, page 29:
196    *
197    *     "(GS Number of URB Entries)
198    *      Range [0,256] in multiples of 4
199    *            [0, 254] in multiples of 4[DevSNBGT1]"
200    *
201    *     "(GS URB Entry Allocation Size)
202    *      Range [0,4] = [1,5] 1024-bit URB rows"
203    */
204   const int max_entry_count = (dev->gt == 2) ? 256 : 252;
205   const int row_size = 1024 / 8;
206   int row_count, entry_count;
207
208   ILO_DEV_ASSERT(dev, 6, 6);
209
210   row_count = (info->gs_entry_size + row_size - 1) / row_size;
211   if (row_count > 5)
212      return false;
213   else if (!row_count)
214      row_count++;
215
216   entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count);
217   if (entry_count > max_entry_count)
218      entry_count = max_entry_count;
219   entry_count &= ~3;
220
221   conf->gs_entry_rows = row_count;
222   conf->gs_entry_count = entry_count;
223
224   return true;
225}
226
227static bool
228urb_init_gen7_vs_entry(const struct ilo_dev *dev,
229                       const struct ilo_state_urb_info *info,
230                       struct urb_configuration *conf)
231{
232   /*
233    * From the Ivy Bridge PRM, volume 2 part 1, page 34-35:
234    *
235    *     "VS URB Entry Allocation Size equal to 4(5 512-bit URB rows) may
236    *      cause performance to decrease due to banking in the URB. Element
237    *      sizes of 16 to 20 should be programmed with six 512-bit URB rows."
238    *
239    *     "(VS URB Entry Allocation Size)
240    *      Format: U9-1 count of 512-bit units"
241    *
242    *     "(VS Number of URB Entries)
243    *      [32,704]
244    *      [32,512]
245    *
246    *      Programming Restriction: VS Number of URB Entries must be divisible
247    *      by 8 if the VS URB Entry Allocation Size is less than 9 512-bit URB
248    *      entries."2:0" = reserved "000b""
249    *
250    * From the Haswell PRM, volume 2b, page 847:
251    *
252    *     "(VS Number of URB Entries)
253    *      [64,1664] DevHSW:GT3
254    *      [64,1664] DevHSW:GT2
255    *      [32,640]  DevHSW:GT1"
256    */
257   const int row_size = 512 / 8;
258   int row_count, entry_count;
259   int entry_size;
260   int max_entry_count, min_entry_count;
261
262   ILO_DEV_ASSERT(dev, 7, 8);
263
264   /*
265    * From the Ivy Bridge PRM, volume 2 part 1, page 35:
266    *
267    *     "Programming Restriction: As the VS URB entry serves as both the
268    *      per-vertex input and output of the VS shader, the VS URB Allocation
269    *      Size must be sized to the maximum of the vertex input and output
270    *      structures."
271    *
272    * From the Ivy Bridge PRM, volume 2 part 1, page 42:
273    *
274    *     "If the VS function is enabled, the VF-written VUEs are not required
275    *      to have Vertex Headers, as the VS-incoming vertices are guaranteed
276    *      to be consumed by the VS (i.e., the VS thread is responsible for
277    *      overwriting the input vertex data)."
278    *
279    * VE and VS share the same VUE for each vertex.
280    */
281   entry_size = info->vs_entry_size;
282   if (entry_size < info->ve_entry_size)
283      entry_size = info->ve_entry_size;
284
285   row_count = (entry_size + row_size - 1) / row_size;
286   if (row_count == 5 || !row_count)
287      row_count++;
288
289   entry_count = conf->vs_urb_alloc_8kb * 8192 / (row_size * row_count);
290   if (row_count < 9)
291      entry_count &= ~7;
292
293   switch (ilo_dev_gen(dev)) {
294   case ILO_GEN(8):
295   case ILO_GEN(7.5):
296      max_entry_count = (dev->gt >= 2) ? 1664 : 640;
297      min_entry_count = (dev->gt >= 2) ? 64 : 32;
298      break;
299   case ILO_GEN(7):
300      max_entry_count = (dev->gt == 2) ? 704 : 512;
301      min_entry_count = 32;
302      break;
303   default:
304      assert(!"unexpected gen");
305      return false;
306      break;
307   }
308
309   if (entry_count > max_entry_count)
310      entry_count = max_entry_count;
311   else if (entry_count < min_entry_count)
312      return false;
313
314   conf->vs_entry_rows = row_count;
315   conf->vs_entry_count = entry_count;
316
317   return true;
318}
319
320static bool
321urb_init_gen7_hs_entry(const struct ilo_dev *dev,
322                       const struct ilo_state_urb_info *info,
323                       struct urb_configuration *conf)
324{
325   /*
326    * From the Ivy Bridge PRM, volume 2 part 1, page 37:
327    *
328    *     "HS Number of URB Entries must be divisible by 8 if the HS URB Entry
329    *      Allocation Size is less than 9 512-bit URB
330    *      entries."2:0" = reserved "000"
331    *
332    *      [0,64]
333    *      [0,32]"
334    *
335    * From the Haswell PRM, volume 2b, page 849:
336    *
337    *     "(HS Number of URB Entries)
338    *      [0,128] DevHSW:GT2
339    *      [0,64]  DevHSW:GT1"
340    */
341   const int row_size = 512 / 8;
342   int row_count, entry_count;
343   int max_entry_count;
344
345   ILO_DEV_ASSERT(dev, 7, 8);
346
347   row_count = (info->hs_entry_size + row_size - 1) / row_size;
348   if (!row_count)
349      row_count++;
350
351   entry_count = conf->hs_urb_alloc_8kb * 8192 / (row_size * row_count);
352   if (row_count < 9)
353      entry_count &= ~7;
354
355   switch (ilo_dev_gen(dev)) {
356   case ILO_GEN(8):
357   case ILO_GEN(7.5):
358      max_entry_count = (dev->gt >= 2) ? 128 : 64;
359      break;
360   case ILO_GEN(7):
361      max_entry_count = (dev->gt == 2) ? 64 : 32;
362      break;
363   default:
364      assert(!"unexpected gen");
365      return false;
366      break;
367   }
368
369   if (entry_count > max_entry_count)
370      entry_count = max_entry_count;
371   else if (info->hs_entry_size && !entry_count)
372      return false;
373
374   conf->hs_entry_rows = row_count;
375   conf->hs_entry_count = entry_count;
376
377   return true;
378}
379
380static bool
381urb_init_gen7_ds_entry(const struct ilo_dev *dev,
382                       const struct ilo_state_urb_info *info,
383                       struct urb_configuration *conf)
384{
385   /*
386    * From the Ivy Bridge PRM, volume 2 part 1, page 38:
387    *
388    *     "(DS URB Entry Allocation Size)
389    *      [0,9]"
390    *
391    *     "(DS Number of URB Entries) If Domain Shader Thread Dispatch is
392    *      Enabled then the minimum number handles that must be allocated is
393    *      138 URB entries.
394    *      "2:0" = reserved "000"
395    *
396    *      [0,448]
397    *      [0,288]
398    *
399    *      DS Number of URB Entries must be divisible by 8 if the DS URB Entry
400    *      Allocation Size is less than 9 512-bit URB entries.If Domain Shader
401    *      Thread Dispatch is Enabled then the minimum number of handles that
402    *      must be allocated is 10 URB entries."
403    *
404    * From the Haswell PRM, volume 2b, page 851:
405    *
406    *     "(DS Number of URB Entries)
407    *      [0,960] DevHSW:GT2
408    *      [0,384] DevHSW:GT1"
409    */
410   const int row_size = 512 / 8;
411   int row_count, entry_count;
412   int max_entry_count;
413
414   ILO_DEV_ASSERT(dev, 7, 8);
415
416   row_count = (info->ds_entry_size + row_size - 1) / row_size;
417   if (row_count > 10)
418      return false;
419   else if (!row_count)
420      row_count++;
421
422   entry_count = conf->ds_urb_alloc_8kb * 8192 / (row_size * row_count);
423   if (row_count < 9)
424      entry_count &= ~7;
425
426   switch (ilo_dev_gen(dev)) {
427   case ILO_GEN(8):
428   case ILO_GEN(7.5):
429      max_entry_count = (dev->gt >= 2) ? 960 : 384;
430      break;
431   case ILO_GEN(7):
432      max_entry_count = (dev->gt == 2) ? 448 : 288;
433      break;
434   default:
435      assert(!"unexpected gen");
436      return false;
437      break;
438   }
439
440   if (entry_count > max_entry_count)
441      entry_count = max_entry_count;
442   else if (info->ds_entry_size && entry_count < 10)
443      return false;
444
445   conf->ds_entry_rows = row_count;
446   conf->ds_entry_count = entry_count;
447
448   return true;
449}
450
451static bool
452urb_init_gen7_gs_entry(const struct ilo_dev *dev,
453                       const struct ilo_state_urb_info *info,
454                       struct urb_configuration *conf)
455{
456   /*
457    * From the Ivy Bridge PRM, volume 2 part 1, page 40:
458    *
459    *     "(GS Number of URB Entries) GS Number of URB Entries must be
460    *      divisible by 8 if the GS URB Entry Allocation Size is less than 9
461    *      512-bit URB entries.
462    *      "2:0" = reserved "000"
463    *
464    *      [0,320]
465    *      [0,192]"
466    *
467    * From the Ivy Bridge PRM, volume 2 part 1, page 171:
468    *
469    *     "(DUAL_INSTANCE and DUAL_OBJECT) The GS must be allocated at least
470    *      two URB handles or behavior is UNDEFINED."
471    *
472    * From the Haswell PRM, volume 2b, page 853:
473    *
474    *     "(GS Number of URB Entries)
475    *      [0,640] DevHSW:GT2
476    *      [0,256] DevHSW:GT1
477    *
478    *      Only if GS is disabled can this field be programmed to 0.  If GS is
479    *      enabled this field shall be programmed to a value greater than 0.
480    *      For GS Dispatch Mode "Single", this field shall be programmed to a
481    *      value greater than or equal to 1. For other GS Dispatch Modes,
482    *      refer to the definition of Dispatch Mode (3DSTATE_GS) for minimum
483    *      values of this field."
484    */
485   const int row_size = 512 / 8;
486   int row_count, entry_count;
487   int max_entry_count;
488
489   ILO_DEV_ASSERT(dev, 7, 8);
490
491   row_count = (info->gs_entry_size + row_size - 1) / row_size;
492   if (!row_count)
493      row_count++;
494
495   entry_count = conf->gs_urb_alloc_8kb * 8192 / (row_size * row_count);
496   if (row_count < 9)
497      entry_count &= ~7;
498
499   switch (ilo_dev_gen(dev)) {
500   case ILO_GEN(8):
501   case ILO_GEN(7.5):
502      max_entry_count = (dev->gt >= 2) ? 640 : 256;
503      break;
504   case ILO_GEN(7):
505      max_entry_count = (dev->gt == 2) ? 320 : 192;
506      break;
507   default:
508      assert(!"unexpected gen");
509      return false;
510      break;
511   }
512
513   if (entry_count > max_entry_count)
514      entry_count = max_entry_count;
515   else if (info->gs_entry_size && entry_count < 2)
516      return false;
517
518   conf->gs_entry_rows = row_count;
519   conf->gs_entry_count = entry_count;
520
521   return true;
522}
523
524static bool
525urb_get_gen6_configuration(const struct ilo_dev *dev,
526                           const struct ilo_state_urb_info *info,
527                           struct urb_configuration *conf)
528{
529   ILO_DEV_ASSERT(dev, 6, 8);
530
531   memset(conf, 0, sizeof(*conf));
532
533   if (ilo_dev_gen(dev) >= ILO_GEN(7))
534      urb_alloc_gen7_pcb(dev, info, conf);
535
536   urb_alloc_gen6_urb(dev, info, conf);
537
538   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
539      if (!urb_init_gen7_vs_entry(dev, info, conf) ||
540          !urb_init_gen7_hs_entry(dev, info, conf) ||
541          !urb_init_gen7_ds_entry(dev, info, conf) ||
542          !urb_init_gen7_gs_entry(dev, info, conf))
543         return false;
544   } else {
545      if (!urb_init_gen6_vs_entry(dev, info, conf) ||
546          !urb_init_gen6_gs_entry(dev, info, conf))
547         return false;
548   }
549
550   return true;
551}
552
553static bool
554urb_set_gen7_3dstate_push_constant_alloc(struct ilo_state_urb *urb,
555                                         const struct ilo_dev *dev,
556                                         const struct ilo_state_urb_info *info,
557                                         const struct urb_configuration *conf)
558{
559   uint32_t dw1[5];
560   uint8_t sizes_kb[5], offset_kb;
561   int i;
562
563   ILO_DEV_ASSERT(dev, 7, 8);
564
565   sizes_kb[0] = conf->vs_pcb_alloc_kb;
566   sizes_kb[1] = conf->hs_pcb_alloc_kb;
567   sizes_kb[2] = conf->ds_pcb_alloc_kb;
568   sizes_kb[3] = conf->gs_pcb_alloc_kb;
569   sizes_kb[4] = conf->ps_pcb_alloc_kb;
570   offset_kb = 0;
571
572   for (i = 0; i < 5; i++) {
573      /* careful for the valid range of offsets */
574      if (sizes_kb[i]) {
575         dw1[i] = offset_kb << GEN7_PCB_ALLOC_DW1_OFFSET__SHIFT |
576                  sizes_kb[i] << GEN7_PCB_ALLOC_DW1_SIZE__SHIFT;
577         offset_kb += sizes_kb[i];
578      } else {
579         dw1[i] = 0;
580      }
581   }
582
583   STATIC_ASSERT(ARRAY_SIZE(urb->pcb) >= 5);
584   memcpy(urb->pcb, dw1, sizeof(dw1));
585
586   return true;
587}
588
589static bool
590urb_set_gen6_3DSTATE_URB(struct ilo_state_urb *urb,
591                         const struct ilo_dev *dev,
592                         const struct ilo_state_urb_info *info,
593                         const struct urb_configuration *conf)
594{
595   uint32_t dw1, dw2;
596
597   ILO_DEV_ASSERT(dev, 6, 6);
598
599   assert(conf->vs_entry_rows && conf->gs_entry_rows);
600
601   dw1 = (conf->vs_entry_rows - 1) << GEN6_URB_DW1_VS_ENTRY_SIZE__SHIFT |
602         conf->vs_entry_count << GEN6_URB_DW1_VS_ENTRY_COUNT__SHIFT;
603   dw2 = conf->gs_entry_count << GEN6_URB_DW2_GS_ENTRY_COUNT__SHIFT |
604         (conf->gs_entry_rows - 1) << GEN6_URB_DW2_GS_ENTRY_SIZE__SHIFT;
605
606   STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 2);
607   urb->urb[0] = dw1;
608   urb->urb[1] = dw2;
609
610   return true;
611}
612
613static bool
614urb_set_gen7_3dstate_urb(struct ilo_state_urb *urb,
615                         const struct ilo_dev *dev,
616                         const struct ilo_state_urb_info *info,
617                         const struct urb_configuration *conf)
618{
619   uint32_t dw1[4];
620   struct {
621      uint8_t alloc_8kb;
622      uint8_t entry_rows;
623      int entry_count;
624   } stages[4];
625   uint8_t offset_8kb;
626   int i;
627
628   ILO_DEV_ASSERT(dev, 7, 8);
629
630   stages[0].alloc_8kb = conf->vs_urb_alloc_8kb;
631   stages[1].alloc_8kb = conf->hs_urb_alloc_8kb;
632   stages[2].alloc_8kb = conf->ds_urb_alloc_8kb;
633   stages[3].alloc_8kb = conf->gs_urb_alloc_8kb;
634
635   stages[0].entry_rows = conf->vs_entry_rows;
636   stages[1].entry_rows = conf->hs_entry_rows;
637   stages[2].entry_rows = conf->ds_entry_rows;
638   stages[3].entry_rows = conf->gs_entry_rows;
639
640   stages[0].entry_count = conf->vs_entry_count;
641   stages[1].entry_count = conf->hs_entry_count;
642   stages[2].entry_count = conf->ds_entry_count;
643   stages[3].entry_count = conf->gs_entry_count;
644
645   offset_8kb = conf->urb_offset_8kb;
646
647   for (i = 0; i < 4; i++) {
648      /* careful for the valid range of offsets */
649      if (stages[i].alloc_8kb) {
650         assert(stages[i].entry_rows);
651         dw1[i] =
652            offset_8kb << GEN7_URB_DW1_OFFSET__SHIFT |
653            (stages[i].entry_rows - 1) << GEN7_URB_DW1_ENTRY_SIZE__SHIFT |
654            stages[i].entry_count << GEN7_URB_DW1_ENTRY_COUNT__SHIFT;
655         offset_8kb += stages[i].alloc_8kb;
656      } else {
657         dw1[i] = 0;
658      }
659   }
660
661   STATIC_ASSERT(ARRAY_SIZE(urb->urb) >= 4);
662   memcpy(urb->urb, dw1, sizeof(dw1));
663
664   return true;
665}
666
667bool
668ilo_state_urb_init(struct ilo_state_urb *urb,
669                   const struct ilo_dev *dev,
670                   const struct ilo_state_urb_info *info)
671{
672   assert(ilo_is_zeroed(urb, sizeof(*urb)));
673   return ilo_state_urb_set_info(urb, dev, info);
674}
675
676bool
677ilo_state_urb_init_for_rectlist(struct ilo_state_urb *urb,
678                                const struct ilo_dev *dev,
679                                uint8_t vf_attr_count)
680{
681   struct ilo_state_urb_info info;
682
683   memset(&info, 0, sizeof(info));
684   info.ve_entry_size = sizeof(uint32_t) * 4 * vf_attr_count;
685
686   return ilo_state_urb_init(urb, dev, &info);
687}
688
689bool
690ilo_state_urb_set_info(struct ilo_state_urb *urb,
691                       const struct ilo_dev *dev,
692                       const struct ilo_state_urb_info *info)
693{
694   struct urb_configuration conf;
695   bool ret = true;
696
697   ret &= urb_get_gen6_configuration(dev, info, &conf);
698   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
699      ret &= urb_set_gen7_3dstate_push_constant_alloc(urb, dev, info, &conf);
700      ret &= urb_set_gen7_3dstate_urb(urb, dev, info, &conf);
701   } else {
702      ret &= urb_set_gen6_3DSTATE_URB(urb, dev, info, &conf);
703   }
704
705   assert(ret);
706
707   return ret;
708}
709
710void
711ilo_state_urb_full_delta(const struct ilo_state_urb *urb,
712                         const struct ilo_dev *dev,
713                         struct ilo_state_urb_delta *delta)
714{
715   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
716      delta->dirty = ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
717                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
718                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
719                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
720                     ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS |
721                     ILO_STATE_URB_3DSTATE_URB_VS |
722                     ILO_STATE_URB_3DSTATE_URB_HS |
723                     ILO_STATE_URB_3DSTATE_URB_DS |
724                     ILO_STATE_URB_3DSTATE_URB_GS;
725   } else {
726      delta->dirty = ILO_STATE_URB_3DSTATE_URB_VS |
727                     ILO_STATE_URB_3DSTATE_URB_GS;
728   }
729}
730
731void
732ilo_state_urb_get_delta(const struct ilo_state_urb *urb,
733                        const struct ilo_dev *dev,
734                        const struct ilo_state_urb *old,
735                        struct ilo_state_urb_delta *delta)
736{
737   delta->dirty = 0;
738
739   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
740      if (memcmp(urb->pcb, old->pcb, sizeof(urb->pcb))) {
741         delta->dirty |= ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
742                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
743                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
744                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
745                         ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS;
746      }
747
748      /*
749       * From the Ivy Bridge PRM, volume 2 part 1, page 34:
750       *
751       *     "3DSTATE_URB_HS, 3DSTATE_URB_DS, and 3DSTATE_URB_GS must also be
752       *      programmed in order for the programming of this state
753       *      (3DSTATE_URB_VS) to be valid."
754       *
755       * The same is true for the other three states.
756       */
757      if (memcmp(urb->urb, old->urb, sizeof(urb->urb))) {
758         delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS |
759                         ILO_STATE_URB_3DSTATE_URB_HS |
760                         ILO_STATE_URB_3DSTATE_URB_DS |
761                         ILO_STATE_URB_3DSTATE_URB_GS;
762      }
763   } else {
764      if (memcmp(urb->urb, old->urb, sizeof(uint32_t) * 2)) {
765         delta->dirty |= ILO_STATE_URB_3DSTATE_URB_VS |
766                         ILO_STATE_URB_3DSTATE_URB_GS;
767      }
768   }
769}
770