• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2012-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 #include "core/ilo_builder_3d.h"
29 #include "core/ilo_builder_media.h"
30 
31 #include "ilo_common.h"
32 #include "ilo_blitter.h"
33 #include "ilo_shader.h"
34 #include "ilo_state.h"
35 #include "ilo_render_gen.h"
36 
37 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
38 
39 static void
gen6_emit_draw_dynamic_viewports(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)40 gen6_emit_draw_dynamic_viewports(struct ilo_render *r,
41                                  const struct ilo_state_vector *vec,
42                                  struct ilo_render_draw_session *session)
43 {
44    ILO_DEV_ASSERT(r->dev, 6, 6);
45 
46    /* CLIP_VIEWPORT, SF_VIEWPORT, and CC_VIEWPORT */
47    if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT |
48                                    ILO_STATE_VIEWPORT_CC_VIEWPORT)) ||
49        r->state_bo_changed) {
50       r->state.CLIP_VIEWPORT = gen6_CLIP_VIEWPORT(r->builder,
51             &vec->viewport.vp);
52       r->state.SF_VIEWPORT = gen6_SF_VIEWPORT(r->builder, &vec->viewport.vp);
53       r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp);
54 
55       session->viewport_changed = true;
56    }
57 }
58 
59 static void
gen7_emit_draw_dynamic_viewports(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)60 gen7_emit_draw_dynamic_viewports(struct ilo_render *r,
61                                  const struct ilo_state_vector *vec,
62                                  struct ilo_render_draw_session *session)
63 {
64    ILO_DEV_ASSERT(r->dev, 7, 8);
65 
66    /* SF_CLIP_VIEWPORT and CC_VIEWPORT */
67    if ((session->vp_delta.dirty & (ILO_STATE_VIEWPORT_SF_CLIP_VIEWPORT |
68                                    ILO_STATE_VIEWPORT_CC_VIEWPORT)) ||
69        r->state_bo_changed) {
70       r->state.SF_CLIP_VIEWPORT = gen7_SF_CLIP_VIEWPORT(r->builder,
71             &vec->viewport.vp);
72       r->state.CC_VIEWPORT = gen6_CC_VIEWPORT(r->builder, &vec->viewport.vp);
73 
74       session->viewport_changed = true;
75    }
76 }
77 
78 static void
gen6_emit_draw_dynamic_scissors(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)79 gen6_emit_draw_dynamic_scissors(struct ilo_render *r,
80                                 const struct ilo_state_vector *vec,
81                                 struct ilo_render_draw_session *session)
82 {
83    ILO_DEV_ASSERT(r->dev, 6, 8);
84 
85    /* SCISSOR_RECT */
86    if ((session->vp_delta.dirty & ILO_STATE_VIEWPORT_SCISSOR_RECT) ||
87        r->state_bo_changed) {
88       r->state.SCISSOR_RECT = gen6_SCISSOR_RECT(r->builder,
89             &vec->viewport.vp);
90 
91       session->scissor_changed = true;
92    }
93 }
94 
95 static void
gen6_emit_draw_dynamic_cc(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)96 gen6_emit_draw_dynamic_cc(struct ilo_render *r,
97                           const struct ilo_state_vector *vec,
98                           struct ilo_render_draw_session *session)
99 {
100    ILO_DEV_ASSERT(r->dev, 6, 8);
101 
102    /* BLEND_STATE */
103    if ((session->cc_delta.dirty & ILO_STATE_CC_BLEND_STATE) ||
104         r->state_bo_changed) {
105       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
106          r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder, &vec->blend->cc);
107       else
108          r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, &vec->blend->cc);
109 
110       session->blend_changed = true;
111    }
112 
113    /* COLOR_CALC_STATE */
114    if ((session->cc_delta.dirty & ILO_STATE_CC_COLOR_CALC_STATE) ||
115        r->state_bo_changed) {
116       r->state.COLOR_CALC_STATE =
117          gen6_COLOR_CALC_STATE(r->builder, &vec->blend->cc);
118       session->cc_changed = true;
119    }
120 
121    /* DEPTH_STENCIL_STATE */
122    if (ilo_dev_gen(r->dev) < ILO_GEN(8) &&
123        ((session->cc_delta.dirty & ILO_STATE_CC_DEPTH_STENCIL_STATE) ||
124         r->state_bo_changed)) {
125       r->state.DEPTH_STENCIL_STATE =
126          gen6_DEPTH_STENCIL_STATE(r->builder, &vec->blend->cc);
127       session->dsa_changed = true;
128    }
129 }
130 
131 static void
gen6_emit_draw_dynamic_samplers(struct ilo_render * r,const struct ilo_state_vector * vec,int shader_type,struct ilo_render_draw_session * session)132 gen6_emit_draw_dynamic_samplers(struct ilo_render *r,
133                                 const struct ilo_state_vector *vec,
134                                 int shader_type,
135                                 struct ilo_render_draw_session *session)
136 {
137    const struct ilo_view_cso * const *views =
138       (const struct ilo_view_cso **) vec->view[shader_type].states;
139    struct ilo_state_sampler samplers[ILO_MAX_SAMPLERS];
140    uint32_t *sampler_state, *border_color_state;
141    int sampler_count, i;
142    bool emit_border_color = false;
143    bool skip = false;
144 
145    ILO_DEV_ASSERT(r->dev, 6, 8);
146 
147    /* SAMPLER_BORDER_COLOR_STATE and SAMPLER_STATE */
148    switch (shader_type) {
149    case PIPE_SHADER_VERTEX:
150       if (DIRTY(VS) || DIRTY(SAMPLER_VS) || DIRTY(VIEW_VS)) {
151          sampler_state = &r->state.vs.SAMPLER_STATE;
152          border_color_state = r->state.vs.SAMPLER_BORDER_COLOR_STATE;
153 
154          if (DIRTY(VS) || DIRTY(SAMPLER_VS))
155             emit_border_color = true;
156 
157          sampler_count = (vec->vs) ? ilo_shader_get_kernel_param(vec->vs,
158                ILO_KERNEL_SAMPLER_COUNT) : 0;
159 
160          session->sampler_vs_changed = true;
161       } else {
162          skip = true;
163       }
164       break;
165    case PIPE_SHADER_FRAGMENT:
166       if (DIRTY(FS) || DIRTY(SAMPLER_FS) || DIRTY(VIEW_FS)) {
167          sampler_state = &r->state.wm.SAMPLER_STATE;
168          border_color_state = r->state.wm.SAMPLER_BORDER_COLOR_STATE;
169 
170          if (DIRTY(VS) || DIRTY(SAMPLER_FS))
171             emit_border_color = true;
172 
173          sampler_count = (vec->fs) ? ilo_shader_get_kernel_param(vec->fs,
174                ILO_KERNEL_SAMPLER_COUNT) : 0;
175 
176          session->sampler_fs_changed = true;
177       } else {
178          skip = true;
179       }
180       break;
181    default:
182       skip = true;
183       break;
184    }
185 
186    if (skip)
187       return;
188 
189    assert(sampler_count <= ARRAY_SIZE(vec->view[shader_type].states) &&
190           sampler_count <= ARRAY_SIZE(vec->sampler[shader_type].cso));
191 
192    if (emit_border_color) {
193       for (i = 0; i < sampler_count; i++) {
194          const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
195 
196          border_color_state[i] = (cso) ?
197             gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, &cso->border) : 0;
198       }
199    }
200 
201    for (i = 0; i < sampler_count; i++) {
202       const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
203 
204       if (cso && views[i]) {
205          samplers[i] = cso->sampler;
206          ilo_state_sampler_set_surface(&samplers[i],
207                r->dev, &views[i]->surface);
208       } else {
209          samplers[i] = vec->disabled_sampler;
210       }
211    }
212 
213    *sampler_state = gen6_SAMPLER_STATE(r->builder, samplers,
214          border_color_state, sampler_count);
215 }
216 
217 static void
gen6_emit_draw_dynamic_pcb(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)218 gen6_emit_draw_dynamic_pcb(struct ilo_render *r,
219                            const struct ilo_state_vector *vec,
220                            struct ilo_render_draw_session *session)
221 {
222    ILO_DEV_ASSERT(r->dev, 6, 8);
223 
224    /* push constant buffer for VS */
225    if (DIRTY(VS) || DIRTY(CBUF) || DIRTY(CLIP)) {
226       const int cbuf0_size = (vec->vs) ?
227             ilo_shader_get_kernel_param(vec->vs,
228                   ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
229       const int clip_state_size = (vec->vs) ?
230             ilo_shader_get_kernel_param(vec->vs,
231                   ILO_KERNEL_VS_PCB_UCP_SIZE) : 0;
232       const int total_size = cbuf0_size + clip_state_size;
233 
234       if (total_size) {
235          void *pcb;
236 
237          r->state.vs.PUSH_CONSTANT_BUFFER =
238             gen6_push_constant_buffer(r->builder, total_size, &pcb);
239          r->state.vs.PUSH_CONSTANT_BUFFER_size = total_size;
240 
241          if (cbuf0_size) {
242             const struct ilo_cbuf_state *cbuf =
243                &vec->cbuf[PIPE_SHADER_VERTEX];
244 
245             if (cbuf0_size <= cbuf->cso[0].info.size) {
246                memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
247             } else {
248                memcpy(pcb, cbuf->cso[0].user_buffer,
249                      cbuf->cso[0].info.size);
250                memset(pcb + cbuf->cso[0].info.size, 0,
251                      cbuf0_size - cbuf->cso[0].info.size);
252             }
253 
254             pcb += cbuf0_size;
255          }
256 
257          if (clip_state_size)
258             memcpy(pcb, &vec->clip, clip_state_size);
259 
260          session->pcb_vs_changed = true;
261       } else if (r->state.vs.PUSH_CONSTANT_BUFFER_size) {
262          r->state.vs.PUSH_CONSTANT_BUFFER = 0;
263          r->state.vs.PUSH_CONSTANT_BUFFER_size = 0;
264 
265          session->pcb_vs_changed = true;
266       }
267    }
268 
269    /* push constant buffer for FS */
270    if (DIRTY(FS) || DIRTY(CBUF)) {
271       const int cbuf0_size = (vec->fs) ?
272          ilo_shader_get_kernel_param(vec->fs, ILO_KERNEL_PCB_CBUF0_SIZE) : 0;
273 
274       if (cbuf0_size) {
275          const struct ilo_cbuf_state *cbuf = &vec->cbuf[PIPE_SHADER_FRAGMENT];
276          void *pcb;
277 
278          r->state.wm.PUSH_CONSTANT_BUFFER =
279             gen6_push_constant_buffer(r->builder, cbuf0_size, &pcb);
280          r->state.wm.PUSH_CONSTANT_BUFFER_size = cbuf0_size;
281 
282          if (cbuf0_size <= cbuf->cso[0].info.size) {
283             memcpy(pcb, cbuf->cso[0].user_buffer, cbuf0_size);
284          } else {
285             memcpy(pcb, cbuf->cso[0].user_buffer,
286                   cbuf->cso[0].info.size);
287             memset(pcb + cbuf->cso[0].info.size, 0,
288                   cbuf0_size - cbuf->cso[0].info.size);
289          }
290 
291          session->pcb_fs_changed = true;
292       } else if (r->state.wm.PUSH_CONSTANT_BUFFER_size) {
293          r->state.wm.PUSH_CONSTANT_BUFFER = 0;
294          r->state.wm.PUSH_CONSTANT_BUFFER_size = 0;
295 
296          session->pcb_fs_changed = true;
297       }
298    }
299 }
300 
301 #undef DIRTY
302 
303 int
ilo_render_get_draw_dynamic_states_len(const struct ilo_render * render,const struct ilo_state_vector * vec)304 ilo_render_get_draw_dynamic_states_len(const struct ilo_render *render,
305                                        const struct ilo_state_vector *vec)
306 {
307    static int static_len;
308    int sh_type, len;
309 
310    ILO_DEV_ASSERT(render->dev, 6, 8);
311 
312    if (!static_len) {
313       /* 64 bytes, or 16 dwords */
314       const int alignment = 64 / 4;
315 
316       /* pad first */
317       len = alignment - 1;
318 
319       /* CC states */
320       len += align(GEN6_BLEND_STATE__SIZE, alignment);
321       len += align(GEN6_COLOR_CALC_STATE__SIZE, alignment);
322       if (ilo_dev_gen(render->dev) < ILO_GEN(8))
323          len += align(GEN6_DEPTH_STENCIL_STATE__SIZE, alignment);
324 
325       /* viewport arrays */
326       if (ilo_dev_gen(render->dev) >= ILO_GEN(7)) {
327          len += 15 + /* pad first */
328             align(GEN7_SF_CLIP_VIEWPORT__SIZE, 16) +
329             align(GEN6_CC_VIEWPORT__SIZE, 8) +
330             align(GEN6_SCISSOR_RECT__SIZE, 8);
331       } else {
332          len += 7 + /* pad first */
333             align(GEN6_SF_VIEWPORT__SIZE, 8) +
334             align(GEN6_CLIP_VIEWPORT__SIZE, 8) +
335             align(GEN6_CC_VIEWPORT__SIZE, 8) +
336             align(GEN6_SCISSOR_RECT__SIZE, 8);
337       }
338 
339       static_len = len;
340    }
341 
342    len = static_len;
343 
344    for (sh_type = 0; sh_type < PIPE_SHADER_TYPES; sh_type++) {
345       const int alignment = 32 / 4;
346       int num_samplers = 0, pcb_len = 0;
347 
348       switch (sh_type) {
349       case PIPE_SHADER_VERTEX:
350          if (vec->vs) {
351             num_samplers = ilo_shader_get_kernel_param(vec->vs,
352                   ILO_KERNEL_SAMPLER_COUNT);
353             pcb_len = ilo_shader_get_kernel_param(vec->vs,
354                   ILO_KERNEL_PCB_CBUF0_SIZE);
355             pcb_len += ilo_shader_get_kernel_param(vec->vs,
356                   ILO_KERNEL_VS_PCB_UCP_SIZE);
357          }
358          break;
359       case PIPE_SHADER_GEOMETRY:
360          break;
361       case PIPE_SHADER_FRAGMENT:
362          if (vec->fs) {
363             num_samplers = ilo_shader_get_kernel_param(vec->fs,
364                   ILO_KERNEL_SAMPLER_COUNT);
365             pcb_len = ilo_shader_get_kernel_param(vec->fs,
366                   ILO_KERNEL_PCB_CBUF0_SIZE);
367          }
368          break;
369       default:
370          break;
371       }
372 
373       /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */
374       if (num_samplers) {
375          /* prefetches are done in multiples of 4 */
376          num_samplers = align(num_samplers, 4);
377 
378          len += align(GEN6_SAMPLER_STATE__SIZE * num_samplers, alignment);
379 
380          if (ilo_dev_gen(render->dev) >= ILO_GEN(8)) {
381             len += align(GEN6_SAMPLER_BORDER_COLOR_STATE__SIZE, 64 / 4) *
382                num_samplers;
383          } else {
384             len += align(GEN6_SAMPLER_BORDER_COLOR_STATE__SIZE, alignment) *
385                num_samplers;
386          }
387       }
388 
389       /* PCB */
390       if (pcb_len)
391          len += align(pcb_len, alignment);
392    }
393 
394    return len;
395 }
396 
397 void
ilo_render_emit_draw_dynamic_states(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)398 ilo_render_emit_draw_dynamic_states(struct ilo_render *render,
399                                     const struct ilo_state_vector *vec,
400                                     struct ilo_render_draw_session *session)
401 {
402    const unsigned dynamic_used = ilo_builder_dynamic_used(render->builder);
403 
404    ILO_DEV_ASSERT(render->dev, 6, 8);
405 
406    if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
407       gen7_emit_draw_dynamic_viewports(render, vec, session);
408    else
409       gen6_emit_draw_dynamic_viewports(render, vec, session);
410 
411    gen6_emit_draw_dynamic_cc(render, vec, session);
412    gen6_emit_draw_dynamic_scissors(render, vec, session);
413    gen6_emit_draw_dynamic_pcb(render, vec, session);
414 
415    gen6_emit_draw_dynamic_samplers(render, vec,
416          PIPE_SHADER_VERTEX, session);
417    gen6_emit_draw_dynamic_samplers(render, vec,
418          PIPE_SHADER_FRAGMENT, session);
419 
420    assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used +
421          ilo_render_get_draw_dynamic_states_len(render, vec));
422 }
423 
424 int
ilo_render_get_rectlist_dynamic_states_len(const struct ilo_render * render,const struct ilo_blitter * blitter)425 ilo_render_get_rectlist_dynamic_states_len(const struct ilo_render *render,
426                                            const struct ilo_blitter *blitter)
427 {
428    ILO_DEV_ASSERT(render->dev, 6, 8);
429 
430    return (ilo_dev_gen(render->dev) >= ILO_GEN(8)) ? 0 : 96;
431 }
432 
433 void
ilo_render_emit_rectlist_dynamic_states(struct ilo_render * render,const struct ilo_blitter * blitter,struct ilo_render_rectlist_session * session)434 ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render,
435                                         const struct ilo_blitter *blitter,
436                                         struct ilo_render_rectlist_session *session)
437 {
438    const unsigned dynamic_used = ilo_builder_dynamic_used(render->builder);
439 
440    ILO_DEV_ASSERT(render->dev, 6, 8);
441 
442    if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
443       return;
444 
445    /* both are inclusive */
446    session->vb_start = gen6_user_vertex_buffer(render->builder,
447          sizeof(blitter->vertices), (const void *) blitter->vertices);
448    session->vb_end = session->vb_start + sizeof(blitter->vertices) - 1;
449 
450    if (blitter->uses & ILO_BLITTER_USE_DSA) {
451       render->state.DEPTH_STENCIL_STATE =
452          gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->cc);
453    }
454 
455    if (blitter->uses & ILO_BLITTER_USE_CC) {
456       render->state.COLOR_CALC_STATE =
457          gen6_COLOR_CALC_STATE(render->builder, &blitter->cc);
458    }
459 
460    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
461       render->state.CC_VIEWPORT =
462          gen6_CC_VIEWPORT(render->builder, &blitter->vp);
463    }
464 
465    assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used +
466          ilo_render_get_rectlist_dynamic_states_len(render, blitter));
467 }
468 
469 static void
gen6_emit_launch_grid_dynamic_samplers(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_launch_grid_session * session)470 gen6_emit_launch_grid_dynamic_samplers(struct ilo_render *r,
471                                        const struct ilo_state_vector *vec,
472                                        struct ilo_render_launch_grid_session *session)
473 {
474    const unsigned shader_type = PIPE_SHADER_COMPUTE;
475    const struct ilo_shader_state *cs = vec->cs;
476    const struct ilo_view_cso * const *views =
477       (const struct ilo_view_cso **) vec->view[shader_type].states;
478    struct ilo_state_sampler samplers[ILO_MAX_SAMPLERS];
479    int sampler_count, i;
480 
481    ILO_DEV_ASSERT(r->dev, 7, 7.5);
482 
483    sampler_count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
484 
485    assert(sampler_count <= ARRAY_SIZE(vec->view[shader_type].states) &&
486           sampler_count <= ARRAY_SIZE(vec->sampler[shader_type].cso));
487 
488    for (i = 0; i < sampler_count; i++) {
489       const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
490 
491       r->state.cs.SAMPLER_BORDER_COLOR_STATE[i] = (cso) ?
492          gen6_SAMPLER_BORDER_COLOR_STATE(r->builder, &cso->border) : 0;
493    }
494 
495    for (i = 0; i < sampler_count; i++) {
496       const struct ilo_sampler_cso *cso = vec->sampler[shader_type].cso[i];
497 
498       if (cso && views[i]) {
499          samplers[i] = cso->sampler;
500          ilo_state_sampler_set_surface(&samplers[i],
501                r->dev, &views[i]->surface);
502       } else {
503          samplers[i] = vec->disabled_sampler;
504       }
505    }
506 
507    r->state.cs.SAMPLER_STATE = gen6_SAMPLER_STATE(r->builder, samplers,
508          r->state.cs.SAMPLER_BORDER_COLOR_STATE, sampler_count);
509 }
510 
511 static void
gen6_emit_launch_grid_dynamic_pcb(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_launch_grid_session * session)512 gen6_emit_launch_grid_dynamic_pcb(struct ilo_render *r,
513                                   const struct ilo_state_vector *vec,
514                                   struct ilo_render_launch_grid_session *session)
515 {
516    r->state.cs.PUSH_CONSTANT_BUFFER = 0;
517    r->state.cs.PUSH_CONSTANT_BUFFER_size = 0;
518 }
519 
520 static void
gen6_emit_launch_grid_dynamic_idrt(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_launch_grid_session * session)521 gen6_emit_launch_grid_dynamic_idrt(struct ilo_render *r,
522                                    const struct ilo_state_vector *vec,
523                                    struct ilo_render_launch_grid_session *session)
524 {
525    const struct ilo_shader_state *cs = vec->cs;
526    struct ilo_state_compute_interface_info interface;
527    struct ilo_state_compute_info info;
528    uint32_t kernel_offset;
529 
530    ILO_DEV_ASSERT(r->dev, 7, 7.5);
531 
532    memset(&interface, 0, sizeof(interface));
533 
534    interface.sampler_count =
535       ilo_shader_get_kernel_param(cs, ILO_KERNEL_SAMPLER_COUNT);
536    interface.surface_count =
537       ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
538    interface.thread_group_size = session->thread_group_size;
539    interface.slm_size =
540       ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_LOCAL_SIZE);
541    interface.curbe_read_length = r->state.cs.PUSH_CONSTANT_BUFFER_size;
542 
543    memset(&info, 0, sizeof(info));
544    info.data = session->compute_data;
545    info.data_size = sizeof(session->compute_data);
546    info.interfaces = &interface;
547    info.interface_count = 1;
548    info.cv_urb_alloc_size = r->dev->urb_size;
549    info.curbe_alloc_size = r->state.cs.PUSH_CONSTANT_BUFFER_size;
550 
551    ilo_state_compute_init(&session->compute, r->dev, &info);
552 
553    kernel_offset = ilo_shader_get_kernel_offset(cs);
554 
555    session->idrt = gen6_INTERFACE_DESCRIPTOR_DATA(r->builder,
556          &session->compute, &kernel_offset,
557          &r->state.cs.SAMPLER_STATE, &r->state.cs.BINDING_TABLE_STATE);
558 
559    session->idrt_size = 32;
560 }
561 
562 int
ilo_render_get_launch_grid_dynamic_states_len(const struct ilo_render * render,const struct ilo_state_vector * vec)563 ilo_render_get_launch_grid_dynamic_states_len(const struct ilo_render *render,
564                                               const struct ilo_state_vector *vec)
565 {
566    const int alignment = 32 / 4;
567    int num_samplers;
568    int len = 0;
569 
570    ILO_DEV_ASSERT(render->dev, 7, 7.5);
571 
572    num_samplers = ilo_shader_get_kernel_param(vec->cs,
573          ILO_KERNEL_SAMPLER_COUNT);
574 
575    /* SAMPLER_STATE array and SAMPLER_BORDER_COLORs */
576    if (num_samplers) {
577       /* prefetches are done in multiples of 4 */
578       num_samplers = align(num_samplers, 4);
579 
580       len += align(GEN6_SAMPLER_STATE__SIZE * num_samplers, alignment) +
581              align(GEN6_SAMPLER_BORDER_COLOR_STATE__SIZE, alignment) *
582              num_samplers;
583    }
584 
585    len += GEN6_INTERFACE_DESCRIPTOR_DATA__SIZE;
586 
587    return len;
588 }
589 
590 void
ilo_render_emit_launch_grid_dynamic_states(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_launch_grid_session * session)591 ilo_render_emit_launch_grid_dynamic_states(struct ilo_render *render,
592                                            const struct ilo_state_vector *vec,
593                                            struct ilo_render_launch_grid_session *session)
594 {
595    const unsigned dynamic_used = ilo_builder_dynamic_used(render->builder);
596 
597    ILO_DEV_ASSERT(render->dev, 7, 7.5);
598 
599    gen6_emit_launch_grid_dynamic_samplers(render, vec, session);
600    gen6_emit_launch_grid_dynamic_pcb(render, vec, session);
601    gen6_emit_launch_grid_dynamic_idrt(render, vec, session);
602 
603    assert(ilo_builder_dynamic_used(render->builder) <= dynamic_used +
604          ilo_render_get_launch_grid_dynamic_states_len(render, vec));
605 }
606