• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2013 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 "genhw/genhw.h"
29 #include "core/ilo_builder_3d.h"
30 #include "core/ilo_builder_render.h"
31 
32 #include "ilo_blitter.h"
33 #include "ilo_resource.h"
34 #include "ilo_shader.h"
35 #include "ilo_state.h"
36 #include "ilo_render_gen.h"
37 
38 static void
gen7_wa_post_3dstate_push_constant_alloc_ps(struct ilo_render * r)39 gen7_wa_post_3dstate_push_constant_alloc_ps(struct ilo_render *r)
40 {
41    /*
42     * From the Ivy Bridge PRM, volume 2 part 1, page 292:
43     *
44     *     "A PIPE_CONTOL command with the CS Stall bit set must be programmed
45     *      in the ring after this instruction
46     *      (3DSTATE_PUSH_CONSTANT_ALLOC_PS)."
47     */
48    const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL;
49 
50    ILO_DEV_ASSERT(r->dev, 7, 7);
51 
52    r->state.deferred_pipe_control_dw1 |= dw1;
53 }
54 
55 static void
gen7_wa_pre_vs(struct ilo_render * r)56 gen7_wa_pre_vs(struct ilo_render *r)
57 {
58    /*
59     * From the Ivy Bridge PRM, volume 2 part 1, page 106:
60     *
61     *     "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth stall
62     *      needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
63     *      3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
64     *      3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
65     *      needs to be sent before any combination of VS associated 3DSTATE."
66     */
67    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_STALL |
68                         GEN6_PIPE_CONTROL_WRITE_IMM;
69 
70    ILO_DEV_ASSERT(r->dev, 7, 7);
71 
72    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
73       ilo_render_pipe_control(r, dw1);
74 }
75 
76 static void
gen7_wa_pre_3dstate_sf_depth_bias(struct ilo_render * r)77 gen7_wa_pre_3dstate_sf_depth_bias(struct ilo_render *r)
78 {
79    /*
80     * From the Ivy Bridge PRM, volume 2 part 1, page 258:
81     *
82     *     "Due to an HW issue driver needs to send a pipe control with stall
83     *      when ever there is state change in depth bias related state (in
84     *      3DSTATE_SF)"
85     */
86    const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL;
87 
88    ILO_DEV_ASSERT(r->dev, 7, 7);
89 
90    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
91       ilo_render_pipe_control(r, dw1);
92 }
93 
94 static void
gen7_wa_pre_3dstate_multisample(struct ilo_render * r)95 gen7_wa_pre_3dstate_multisample(struct ilo_render *r)
96 {
97    /*
98     * From the Ivy Bridge PRM, volume 2 part 1, page 304:
99     *
100     *     "Driver must ierarchi that all the caches in the depth pipe are
101     *      flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
102     *      requires driver to send a PIPE_CONTROL with a CS stall along with a
103     *      Depth Flush prior to this command.
104     */
105    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
106                         GEN6_PIPE_CONTROL_CS_STALL;
107 
108    ILO_DEV_ASSERT(r->dev, 7, 7.5);
109 
110    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
111       ilo_render_pipe_control(r, dw1);
112 }
113 
114 static void
gen7_wa_pre_depth(struct ilo_render * r)115 gen7_wa_pre_depth(struct ilo_render *r)
116 {
117    ILO_DEV_ASSERT(r->dev, 7, 7.5);
118 
119    if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
120       /*
121        * From the Ivy Bridge PRM, volume 2 part 1, page 315:
122        *
123        *     "Driver must send a least one PIPE_CONTROL command with CS Stall
124        *      and a post sync operation prior to the group of depth
125        *      commands(3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
126        *      3DSTATE_STENCIL_BUFFER, and 3DSTATE_HIER_DEPTH_BUFFER)."
127        */
128       const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL |
129                            GEN6_PIPE_CONTROL_WRITE_IMM;
130 
131       if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
132          ilo_render_pipe_control(r, dw1);
133    }
134 
135    /*
136     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
137     *
138     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
139     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
140     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
141     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
142     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
143     *      Depth Flush Bit set, followed by another pipelined depth stall
144     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
145     *      guarantee that the pipeline from WM onwards is already flushed
146     *      (e.g., via a preceding MI_FLUSH)."
147     */
148    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
149    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
150    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
151 }
152 
153 static void
gen7_wa_pre_3dstate_ps_max_threads(struct ilo_render * r)154 gen7_wa_pre_3dstate_ps_max_threads(struct ilo_render *r)
155 {
156    /*
157     * From the Ivy Bridge PRM, volume 2 part 1, page 286:
158     *
159     *     "If this field (Maximum Number of Threads in 3DSTATE_PS) is changed
160     *      between 3DPRIMITIVE commands, a PIPE_CONTROL command with Stall at
161     *      Pixel Scoreboard set is required to be issued."
162     */
163    const uint32_t dw1 = GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
164 
165    ILO_DEV_ASSERT(r->dev, 7, 7.5);
166 
167    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
168       ilo_render_pipe_control(r, dw1);
169 }
170 
171 static void
gen7_wa_post_ps_and_later(struct ilo_render * r)172 gen7_wa_post_ps_and_later(struct ilo_render *r)
173 {
174    /*
175     * From the Ivy Bridge PRM, volume 2 part 1, page 276:
176     *
177     *     "The driver must make sure a PIPE_CONTROL with the Depth Stall
178     *      Enable bit set after all the following states are programmed:
179     *
180     *       - 3DSTATE_PS
181     *       - 3DSTATE_VIEWPORT_STATE_POINTERS_CC
182     *       - 3DSTATE_CONSTANT_PS
183     *       - 3DSTATE_BINDING_TABLE_POINTERS_PS
184     *       - 3DSTATE_SAMPLER_STATE_POINTERS_PS
185     *       - 3DSTATE_CC_STATE_POINTERS
186     *       - 3DSTATE_BLEND_STATE_POINTERS
187     *       - 3DSTATE_DEPTH_STENCIL_STATE_POINTERS"
188     */
189    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_STALL;
190 
191    ILO_DEV_ASSERT(r->dev, 7, 7);
192 
193    r->state.deferred_pipe_control_dw1 |= dw1;
194 }
195 
196 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
197 
198 void
gen7_draw_common_urb(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)199 gen7_draw_common_urb(struct ilo_render *r,
200                      const struct ilo_state_vector *vec,
201                      struct ilo_render_draw_session *session)
202 {
203    /* 3DSTATE_URB_{VS,GS,HS,DS} */
204    if (session->urb_delta.dirty & (ILO_STATE_URB_3DSTATE_URB_VS |
205                                    ILO_STATE_URB_3DSTATE_URB_HS |
206                                    ILO_STATE_URB_3DSTATE_URB_DS |
207                                    ILO_STATE_URB_3DSTATE_URB_GS)) {
208       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
209          gen7_wa_pre_vs(r);
210 
211       gen7_3DSTATE_URB_VS(r->builder, &vec->urb);
212       gen7_3DSTATE_URB_GS(r->builder, &vec->urb);
213       gen7_3DSTATE_URB_HS(r->builder, &vec->urb);
214       gen7_3DSTATE_URB_DS(r->builder, &vec->urb);
215    }
216 }
217 
218 void
gen7_draw_common_pcb_alloc(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)219 gen7_draw_common_pcb_alloc(struct ilo_render *r,
220                            const struct ilo_state_vector *vec,
221                            struct ilo_render_draw_session *session)
222 {
223    /* 3DSTATE_PUSH_CONSTANT_ALLOC_{VS,PS} */
224    if (session->urb_delta.dirty &
225          (ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_VS |
226           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_HS |
227           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_DS |
228           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_GS |
229           ILO_STATE_URB_3DSTATE_PUSH_CONSTANT_ALLOC_PS)) {
230       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &vec->urb);
231       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_GS(r->builder, &vec->urb);
232       gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &vec->urb);
233 
234       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
235          gen7_wa_post_3dstate_push_constant_alloc_ps(r);
236    }
237 }
238 
239 void
gen7_draw_common_pointers_1(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)240 gen7_draw_common_pointers_1(struct ilo_render *r,
241                             const struct ilo_state_vector *vec,
242                             struct ilo_render_draw_session *session)
243 {
244    /* 3DSTATE_VIEWPORT_STATE_POINTERS_{CC,SF_CLIP} */
245    if (session->viewport_changed) {
246       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(r->builder,
247             r->state.CC_VIEWPORT);
248 
249       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP(r->builder,
250             r->state.SF_CLIP_VIEWPORT);
251    }
252 }
253 
254 void
gen7_draw_common_pointers_2(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)255 gen7_draw_common_pointers_2(struct ilo_render *r,
256                             const struct ilo_state_vector *vec,
257                             struct ilo_render_draw_session *session)
258 {
259    /* 3DSTATE_BLEND_STATE_POINTERS */
260    if (session->blend_changed) {
261       gen7_3DSTATE_BLEND_STATE_POINTERS(r->builder,
262             r->state.BLEND_STATE);
263    }
264 
265    /* 3DSTATE_CC_STATE_POINTERS */
266    if (session->cc_changed) {
267       gen7_3DSTATE_CC_STATE_POINTERS(r->builder,
268             r->state.COLOR_CALC_STATE);
269    }
270 
271    /* 3DSTATE_DEPTH_STENCIL_STATE_POINTERS */
272    if (ilo_dev_gen(r->dev) < ILO_GEN(8) && session->dsa_changed) {
273       gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(r->builder,
274             r->state.DEPTH_STENCIL_STATE);
275    }
276 }
277 
278 void
gen7_draw_vs(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)279 gen7_draw_vs(struct ilo_render *r,
280              const struct ilo_state_vector *vec,
281              struct ilo_render_draw_session *session)
282 {
283    const bool emit_3dstate_binding_table = session->binding_table_vs_changed;
284    const bool emit_3dstate_sampler_state = session->sampler_vs_changed;
285    /* see gen6_draw_vs() */
286    const bool emit_3dstate_constant_vs = session->pcb_vs_changed;
287    const bool emit_3dstate_vs = (DIRTY(VS) || r->instruction_bo_changed);
288 
289    /* emit depth stall before any of the VS commands */
290    if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
291       if (emit_3dstate_binding_table || emit_3dstate_sampler_state ||
292           emit_3dstate_constant_vs || emit_3dstate_vs)
293          gen7_wa_pre_vs(r);
294    }
295 
296    /* 3DSTATE_BINDING_TABLE_POINTERS_VS */
297    if (emit_3dstate_binding_table) {
298       gen7_3DSTATE_BINDING_TABLE_POINTERS_VS(r->builder,
299               r->state.vs.BINDING_TABLE_STATE);
300    }
301 
302    /* 3DSTATE_SAMPLER_STATE_POINTERS_VS */
303    if (emit_3dstate_sampler_state) {
304       gen7_3DSTATE_SAMPLER_STATE_POINTERS_VS(r->builder,
305               r->state.vs.SAMPLER_STATE);
306    }
307 
308    /* 3DSTATE_CONSTANT_VS */
309    if (emit_3dstate_constant_vs) {
310       gen7_3DSTATE_CONSTANT_VS(r->builder,
311               &r->state.vs.PUSH_CONSTANT_BUFFER,
312               &r->state.vs.PUSH_CONSTANT_BUFFER_size,
313               1);
314    }
315 
316    /* 3DSTATE_VS */
317    if (emit_3dstate_vs) {
318       const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
319       const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
320 
321       if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) {
322          gen8_3DSTATE_VS(r->builder, &cso->vs,
323                kernel_offset, r->vs_scratch.bo);
324       } else {
325          gen6_3DSTATE_VS(r->builder, &cso->vs,
326                kernel_offset, r->vs_scratch.bo);
327       }
328    }
329 }
330 
331 void
gen7_draw_hs(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)332 gen7_draw_hs(struct ilo_render *r,
333              const struct ilo_state_vector *vec,
334              struct ilo_render_draw_session *session)
335 {
336    /* 3DSTATE_CONSTANT_HS and 3DSTATE_HS */
337    if (r->hw_ctx_changed) {
338       const struct ilo_state_hs *hs = &vec->disabled_hs;
339       const uint32_t kernel_offset = 0;
340 
341       gen7_3DSTATE_CONSTANT_HS(r->builder, 0, 0, 0);
342 
343       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
344          gen8_3DSTATE_HS(r->builder, hs, kernel_offset, NULL);
345       else
346          gen7_3DSTATE_HS(r->builder, hs, kernel_offset, NULL);
347    }
348 
349    /* 3DSTATE_BINDING_TABLE_POINTERS_HS */
350    if (r->hw_ctx_changed)
351       gen7_3DSTATE_BINDING_TABLE_POINTERS_HS(r->builder, 0);
352 }
353 
354 void
gen7_draw_te(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)355 gen7_draw_te(struct ilo_render *r,
356              const struct ilo_state_vector *vec,
357              struct ilo_render_draw_session *session)
358 {
359    /* 3DSTATE_TE */
360    if (r->hw_ctx_changed) {
361       const struct ilo_state_ds *ds = &vec->disabled_ds;
362       gen7_3DSTATE_TE(r->builder, ds);
363    }
364 }
365 
366 void
gen7_draw_ds(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)367 gen7_draw_ds(struct ilo_render *r,
368              const struct ilo_state_vector *vec,
369              struct ilo_render_draw_session *session)
370 {
371    /* 3DSTATE_CONSTANT_DS and 3DSTATE_DS */
372    if (r->hw_ctx_changed) {
373       const struct ilo_state_ds *ds = &vec->disabled_ds;
374       const uint32_t kernel_offset = 0;
375 
376       gen7_3DSTATE_CONSTANT_DS(r->builder, 0, 0, 0);
377 
378       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
379          gen8_3DSTATE_DS(r->builder, ds, kernel_offset, NULL);
380       else
381          gen7_3DSTATE_DS(r->builder, ds, kernel_offset, NULL);
382    }
383 
384    /* 3DSTATE_BINDING_TABLE_POINTERS_DS */
385    if (r->hw_ctx_changed)
386       gen7_3DSTATE_BINDING_TABLE_POINTERS_DS(r->builder, 0);
387 
388 }
389 
390 void
gen7_draw_gs(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)391 gen7_draw_gs(struct ilo_render *r,
392              const struct ilo_state_vector *vec,
393              struct ilo_render_draw_session *session)
394 {
395    /* 3DSTATE_CONSTANT_GS and 3DSTATE_GS */
396    if (r->hw_ctx_changed) {
397       const struct ilo_state_gs *gs = &vec->disabled_gs;
398       const uint32_t kernel_offset = 0;
399 
400       gen7_3DSTATE_CONSTANT_GS(r->builder, 0, 0, 0);
401 
402       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
403          gen8_3DSTATE_GS(r->builder, gs, kernel_offset, NULL);
404       else
405          gen7_3DSTATE_GS(r->builder, gs, kernel_offset, NULL);
406    }
407 
408    /* 3DSTATE_BINDING_TABLE_POINTERS_GS */
409    if (session->binding_table_gs_changed) {
410       gen7_3DSTATE_BINDING_TABLE_POINTERS_GS(r->builder,
411             r->state.gs.BINDING_TABLE_STATE);
412    }
413 }
414 
415 void
gen7_draw_sol(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)416 gen7_draw_sol(struct ilo_render *r,
417               const struct ilo_state_vector *vec,
418               struct ilo_render_draw_session *session)
419 {
420    const struct ilo_state_sol *sol;
421    const struct ilo_shader_state *shader;
422    bool dirty_sh = false;
423 
424    if (vec->gs) {
425       shader = vec->gs;
426       dirty_sh = DIRTY(GS);
427    }
428    else {
429       shader = vec->vs;
430       dirty_sh = DIRTY(VS);
431    }
432 
433    sol = ilo_shader_get_kernel_sol(shader);
434 
435    /* 3DSTATE_SO_BUFFER */
436    if ((DIRTY(SO) || dirty_sh || r->batch_bo_changed) &&
437        vec->so.enabled) {
438       int i;
439 
440       for (i = 0; i < ILO_STATE_SOL_MAX_BUFFER_COUNT; i++) {
441          const struct pipe_stream_output_target *target =
442             (i < vec->so.count && vec->so.states[i]) ?
443             vec->so.states[i] : NULL;
444          const struct ilo_state_sol_buffer *sb = (target) ?
445             &((const struct ilo_stream_output_target *) target)->sb :
446             &vec->so.dummy_sb;
447 
448          if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
449             gen8_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
450          else
451             gen7_3DSTATE_SO_BUFFER(r->builder, sol, sb, i);
452       }
453    }
454 
455    /* 3DSTATE_SO_DECL_LIST */
456    if (dirty_sh && vec->so.enabled)
457       gen7_3DSTATE_SO_DECL_LIST(r->builder, sol);
458 
459    /*
460     * From the Ivy Bridge PRM, volume 2 part 1, page 196-197:
461     *
462     *     "Anytime the SOL unit MMIO registers or non-pipeline state are
463     *      written, the SOL unit needs to receive a pipeline state update with
464     *      SOL unit dirty state for information programmed in MMIO/NP to get
465     *      loaded into the SOL unit.
466     *
467     *      The SOL unit incorrectly double buffers MMIO/NP registers and only
468     *      moves them into the design for usage when control topology is
469     *      received with the SOL unit dirty state.
470     *
471     *      If the state does not change, need to resend the same state.
472     *
473     *      Because of corruption, software must flush the whole fixed function
474     *      pipeline when 3DSTATE_STREAMOUT changes state."
475     *
476     * The first and fourth paragraphs are gone on Gen7.5+.
477     */
478 
479    /* 3DSTATE_STREAMOUT */
480    gen7_3DSTATE_STREAMOUT(r->builder, sol);
481 }
482 
483 static void
gen7_draw_sf(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)484 gen7_draw_sf(struct ilo_render *r,
485              const struct ilo_state_vector *vec,
486              struct ilo_render_draw_session *session)
487 {
488    /* 3DSTATE_SBE */
489    if (DIRTY(FS)) {
490       const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
491       gen7_3DSTATE_SBE(r->builder, sbe);
492    }
493 
494    /* 3DSTATE_SF */
495    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF) {
496       if (ilo_dev_gen(r->dev) == ILO_GEN(7))
497          gen7_wa_pre_3dstate_sf_depth_bias(r);
498 
499       gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
500    }
501 }
502 
503 static void
gen7_draw_wm(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)504 gen7_draw_wm(struct ilo_render *r,
505              const struct ilo_state_vector *vec,
506              struct ilo_render_draw_session *session)
507 {
508    const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
509    const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
510 
511    /* 3DSTATE_WM */
512    if (DIRTY(FS) || (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM))
513       gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, &cso->ps);
514 
515    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
516    if (session->binding_table_fs_changed) {
517       gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
518             r->state.wm.BINDING_TABLE_STATE);
519    }
520 
521    /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
522    if (session->sampler_fs_changed) {
523       gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
524             r->state.wm.SAMPLER_STATE);
525    }
526 
527    /* 3DSTATE_CONSTANT_PS */
528    if (session->pcb_fs_changed) {
529       gen7_3DSTATE_CONSTANT_PS(r->builder,
530             &r->state.wm.PUSH_CONSTANT_BUFFER,
531             &r->state.wm.PUSH_CONSTANT_BUFFER_size,
532             1);
533    }
534 
535    /* 3DSTATE_PS */
536    if (DIRTY(FS) || r->instruction_bo_changed) {
537       if (r->hw_ctx_changed)
538          gen7_wa_pre_3dstate_ps_max_threads(r);
539 
540       gen7_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
541    }
542 
543    /* 3DSTATE_SCISSOR_STATE_POINTERS */
544    if (session->scissor_changed) {
545       gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
546             r->state.SCISSOR_RECT);
547    }
548 
549    {
550       const bool emit_3dstate_ps = (DIRTY(FS) || DIRTY(BLEND));
551       const bool emit_3dstate_depth_buffer =
552          (DIRTY(FB) || DIRTY(DSA) || r->state_bo_changed);
553 
554       if (ilo_dev_gen(r->dev) == ILO_GEN(7)) {
555          /* XXX what is the best way to know if this workaround is needed? */
556          if (emit_3dstate_ps ||
557              session->pcb_fs_changed ||
558              session->viewport_changed ||
559              session->binding_table_fs_changed ||
560              session->sampler_fs_changed ||
561              session->cc_changed ||
562              session->blend_changed ||
563              session->dsa_changed)
564             gen7_wa_post_ps_and_later(r);
565       }
566 
567       if (emit_3dstate_depth_buffer)
568          gen7_wa_pre_depth(r);
569    }
570 
571    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
572    if (DIRTY(FB) || r->batch_bo_changed) {
573       const struct ilo_state_zs *zs;
574       uint32_t clear_params;
575 
576       if (vec->fb.state.zsbuf) {
577          const struct ilo_surface_cso *surface =
578             (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
579          const struct ilo_texture_slice *slice =
580             ilo_texture_get_slice(ilo_texture(surface->base.texture),
581                   surface->base.u.tex.level, surface->base.u.tex.first_layer);
582 
583          assert(!surface->is_rt);
584          zs = &surface->u.zs;
585          clear_params = slice->clear_value;
586       }
587       else {
588          zs = &vec->fb.null_zs;
589          clear_params = 0;
590       }
591 
592       gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
593       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
594       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
595       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
596    }
597 }
598 
599 static void
gen7_draw_wm_multisample(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)600 gen7_draw_wm_multisample(struct ilo_render *r,
601                          const struct ilo_state_vector *vec,
602                          struct ilo_render_draw_session *session)
603 {
604    /* 3DSTATE_MULTISAMPLE */
605    if (DIRTY(FB) || (session->rs_delta.dirty &
606             ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
607       const uint8_t sample_count = (vec->fb.num_samples > 4) ? 8 :
608                                    (vec->fb.num_samples > 1) ? 4 : 1;
609 
610       gen7_wa_pre_3dstate_multisample(r);
611 
612       gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
613             &r->sample_pattern, sample_count);
614    }
615 
616    /* 3DSTATE_SAMPLE_MASK */
617    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
618       gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
619 }
620 
621 void
ilo_render_emit_draw_commands_gen7(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)622 ilo_render_emit_draw_commands_gen7(struct ilo_render *render,
623                                    const struct ilo_state_vector *vec,
624                                    struct ilo_render_draw_session *session)
625 {
626    ILO_DEV_ASSERT(render->dev, 7, 7.5);
627 
628    /*
629     * We try to keep the order of the commands match, as closely as possible,
630     * that of the classic i965 driver.  It allows us to compare the command
631     * streams easily.
632     */
633    gen6_draw_common_select(render, vec, session);
634    gen6_draw_common_sip(render, vec, session);
635    gen6_draw_vf_statistics(render, vec, session);
636    gen7_draw_common_pcb_alloc(render, vec, session);
637    gen6_draw_common_base_address(render, vec, session);
638    gen7_draw_common_pointers_1(render, vec, session);
639    gen7_draw_common_urb(render, vec, session);
640    gen7_draw_common_pointers_2(render, vec, session);
641    gen7_draw_wm_multisample(render, vec, session);
642    gen7_draw_gs(render, vec, session);
643    gen7_draw_hs(render, vec, session);
644    gen7_draw_te(render, vec, session);
645    gen7_draw_ds(render, vec, session);
646    gen7_draw_vs(render, vec, session);
647    gen7_draw_sol(render, vec, session);
648    gen6_draw_clip(render, vec, session);
649    gen7_draw_sf(render, vec, session);
650    gen7_draw_wm(render, vec, session);
651    gen6_draw_wm_raster(render, vec, session);
652    gen6_draw_sf_rect(render, vec, session);
653    gen6_draw_vf(render, vec, session);
654 
655    ilo_render_3dprimitive(render, &vec->draw_info);
656 }
657 
658 static void
gen7_rectlist_pcb_alloc(struct ilo_render * r,const struct ilo_blitter * blitter)659 gen7_rectlist_pcb_alloc(struct ilo_render *r,
660                         const struct ilo_blitter *blitter)
661 {
662    gen7_3DSTATE_PUSH_CONSTANT_ALLOC_VS(r->builder, &blitter->urb);
663    gen7_3DSTATE_PUSH_CONSTANT_ALLOC_PS(r->builder, &blitter->urb);
664 
665    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
666       gen7_wa_post_3dstate_push_constant_alloc_ps(r);
667 }
668 
669 static void
gen7_rectlist_urb(struct ilo_render * r,const struct ilo_blitter * blitter)670 gen7_rectlist_urb(struct ilo_render *r,
671                   const struct ilo_blitter *blitter)
672 {
673    gen7_3DSTATE_URB_VS(r->builder, &blitter->urb);
674    gen7_3DSTATE_URB_GS(r->builder, &blitter->urb);
675    gen7_3DSTATE_URB_HS(r->builder, &blitter->urb);
676    gen7_3DSTATE_URB_DS(r->builder, &blitter->urb);
677 }
678 
679 static void
gen7_rectlist_vs_to_sf(struct ilo_render * r,const struct ilo_blitter * blitter)680 gen7_rectlist_vs_to_sf(struct ilo_render *r,
681                        const struct ilo_blitter *blitter)
682 {
683    gen7_3DSTATE_CONSTANT_VS(r->builder, NULL, NULL, 0);
684    gen6_3DSTATE_VS(r->builder, &blitter->vs, 0, NULL);
685 
686    gen7_3DSTATE_CONSTANT_HS(r->builder, NULL, NULL, 0);
687    gen7_3DSTATE_HS(r->builder, &blitter->hs, 0, NULL);
688 
689    gen7_3DSTATE_TE(r->builder, &blitter->ds);
690 
691    gen7_3DSTATE_CONSTANT_DS(r->builder, NULL, NULL, 0);
692    gen7_3DSTATE_DS(r->builder, &blitter->ds, 0, NULL);
693 
694    gen7_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
695    gen7_3DSTATE_GS(r->builder, &blitter->gs, 0, NULL);
696 
697    gen7_3DSTATE_STREAMOUT(r->builder, &blitter->sol);
698 
699    gen6_3DSTATE_CLIP(r->builder, &blitter->fb.rs);
700 
701    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
702       gen7_wa_pre_3dstate_sf_depth_bias(r);
703 
704    gen7_3DSTATE_SF(r->builder, &blitter->fb.rs);
705    gen7_3DSTATE_SBE(r->builder, &blitter->sbe);
706 }
707 
708 static void
gen7_rectlist_wm(struct ilo_render * r,const struct ilo_blitter * blitter)709 gen7_rectlist_wm(struct ilo_render *r,
710                  const struct ilo_blitter *blitter)
711 {
712    gen7_3DSTATE_WM(r->builder, &blitter->fb.rs, &blitter->ps);
713 
714    gen7_3DSTATE_CONSTANT_PS(r->builder, NULL, NULL, 0);
715 
716    gen7_wa_pre_3dstate_ps_max_threads(r);
717    gen7_3DSTATE_PS(r->builder, &blitter->ps, 0, NULL);
718 }
719 
720 static void
gen7_rectlist_wm_depth(struct ilo_render * r,const struct ilo_blitter * blitter)721 gen7_rectlist_wm_depth(struct ilo_render *r,
722                        const struct ilo_blitter *blitter)
723 {
724    gen7_wa_pre_depth(r);
725 
726    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
727                         ILO_BLITTER_USE_FB_STENCIL))
728       gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
729 
730    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
731       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
732             &blitter->fb.dst.u.zs);
733    }
734 
735    if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
736       gen6_3DSTATE_STENCIL_BUFFER(r->builder,
737             &blitter->fb.dst.u.zs);
738    }
739 
740    gen7_3DSTATE_CLEAR_PARAMS(r->builder,
741          blitter->depth_clear_value);
742 }
743 
744 static void
gen7_rectlist_wm_multisample(struct ilo_render * r,const struct ilo_blitter * blitter)745 gen7_rectlist_wm_multisample(struct ilo_render *r,
746                              const struct ilo_blitter *blitter)
747 {
748    const uint8_t sample_count = (blitter->fb.num_samples > 4) ? 8 :
749                                 (blitter->fb.num_samples > 1) ? 4 : 1;
750 
751    gen7_wa_pre_3dstate_multisample(r);
752 
753    gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs,
754          &r->sample_pattern, sample_count);
755 
756    gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
757 }
758 
759 void
ilo_render_emit_rectlist_commands_gen7(struct ilo_render * r,const struct ilo_blitter * blitter,const struct ilo_render_rectlist_session * session)760 ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r,
761                                        const struct ilo_blitter *blitter,
762                                        const struct ilo_render_rectlist_session *session)
763 {
764    ILO_DEV_ASSERT(r->dev, 7, 7.5);
765 
766    gen7_rectlist_wm_multisample(r, blitter);
767 
768    gen6_state_base_address(r->builder, true);
769 
770    gen6_user_3DSTATE_VERTEX_BUFFERS(r->builder,
771          session->vb_start, session->vb_end,
772          sizeof(blitter->vertices[0]));
773 
774    gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf);
775 
776    gen7_rectlist_pcb_alloc(r, blitter);
777 
778    /* needed for any VS-related commands */
779    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
780       gen7_wa_pre_vs(r);
781 
782    gen7_rectlist_urb(r, blitter);
783 
784    if (blitter->uses & ILO_BLITTER_USE_DSA) {
785       gen7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS(r->builder,
786             r->state.DEPTH_STENCIL_STATE);
787    }
788 
789    if (blitter->uses & ILO_BLITTER_USE_CC) {
790       gen7_3DSTATE_CC_STATE_POINTERS(r->builder,
791             r->state.COLOR_CALC_STATE);
792    }
793 
794    gen7_rectlist_vs_to_sf(r, blitter);
795    gen7_rectlist_wm(r, blitter);
796 
797    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
798       gen7_3DSTATE_VIEWPORT_STATE_POINTERS_CC(r->builder,
799             r->state.CC_VIEWPORT);
800    }
801 
802    gen7_rectlist_wm_depth(r, blitter);
803 
804    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
805          blitter->fb.width, blitter->fb.height);
806 
807    if (ilo_dev_gen(r->dev) == ILO_GEN(7))
808       gen7_wa_post_ps_and_later(r);
809 
810    ilo_render_3dprimitive(r, &blitter->draw_info);
811 }
812 
813 int
ilo_render_get_draw_commands_len_gen7(const struct ilo_render * render,const struct ilo_state_vector * vec)814 ilo_render_get_draw_commands_len_gen7(const struct ilo_render *render,
815                                       const struct ilo_state_vector *vec)
816 {
817    static int len;
818 
819    ILO_DEV_ASSERT(render->dev, 7, 7.5);
820 
821    if (!len) {
822       len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
823       len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
824       len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
825       len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
826       len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
827       len += GEN6_PIPE_CONTROL__SIZE * 5;
828 
829       len +=
830          GEN6_STATE_BASE_ADDRESS__SIZE +
831          GEN6_STATE_SIP__SIZE +
832          GEN6_3DSTATE_VF_STATISTICS__SIZE +
833          GEN6_PIPELINE_SELECT__SIZE +
834          GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
835          GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
836          GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
837          GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
838          GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
839          GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
840          GEN6_3DSTATE_INDEX_BUFFER__SIZE +
841          GEN75_3DSTATE_VF__SIZE +
842          GEN6_3DSTATE_VS__SIZE +
843          GEN6_3DSTATE_GS__SIZE +
844          GEN6_3DSTATE_CLIP__SIZE +
845          GEN6_3DSTATE_SF__SIZE +
846          GEN6_3DSTATE_WM__SIZE +
847          GEN6_3DSTATE_SAMPLE_MASK__SIZE +
848          GEN7_3DSTATE_HS__SIZE +
849          GEN7_3DSTATE_TE__SIZE +
850          GEN7_3DSTATE_DS__SIZE +
851          GEN7_3DSTATE_STREAMOUT__SIZE +
852          GEN7_3DSTATE_SBE__SIZE +
853          GEN7_3DSTATE_PS__SIZE +
854          GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
855          GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
856          GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
857          GEN6_3DSTATE_LINE_STIPPLE__SIZE +
858          GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
859          GEN6_3DSTATE_MULTISAMPLE__SIZE +
860          GEN7_3DSTATE_SO_DECL_LIST__SIZE +
861          GEN6_3DPRIMITIVE__SIZE;
862    }
863 
864    return len;
865 }
866