• 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_mi.h"
31 #include "core/ilo_builder_render.h"
32 #include "util/u_prim.h"
33 
34 #include "ilo_blitter.h"
35 #include "ilo_query.h"
36 #include "ilo_resource.h"
37 #include "ilo_shader.h"
38 #include "ilo_state.h"
39 #include "ilo_render_gen.h"
40 
41 /**
42  * This should be called before PIPE_CONTROL.
43  */
44 void
gen6_wa_pre_pipe_control(struct ilo_render * r,uint32_t dw1)45 gen6_wa_pre_pipe_control(struct ilo_render *r, uint32_t dw1)
46 {
47    /*
48     * From the Sandy Bridge PRM, volume 2 part 1, page 60:
49     *
50     *     "Pipe-control with CS-stall bit set must be sent BEFORE the
51     *      pipe-control with a post-sync op and no write-cache flushes."
52     *
53     * This WA may also be triggered indirectly by the other two WAs on the
54     * same page:
55     *
56     *     "Before any depth stall flush (including those produced by
57     *      non-pipelined state commands), software needs to first send a
58     *      PIPE_CONTROL with no bits set except Post-Sync Operation != 0."
59     *
60     *     "Before a PIPE_CONTROL with Write Cache Flush Enable =1, a
61     *      PIPE_CONTROL with any non-zero post-sync-op is required."
62     */
63    const bool direct_wa_cond = (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK) &&
64                                !(dw1 & GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH);
65    const bool indirect_wa_cond = (dw1 & GEN6_PIPE_CONTROL_DEPTH_STALL) |
66                                  (dw1 & GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH);
67 
68    ILO_DEV_ASSERT(r->dev, 6, 6);
69 
70    if (!direct_wa_cond && !indirect_wa_cond)
71       return;
72 
73    if (!(r->state.current_pipe_control_dw1 & GEN6_PIPE_CONTROL_CS_STALL)) {
74       /*
75        * From the Sandy Bridge PRM, volume 2 part 1, page 73:
76        *
77        *     "1 of the following must also be set (when CS stall is set):
78        *
79        *       - Depth Cache Flush Enable ([0] of DW1)
80        *       - Stall at Pixel Scoreboard ([1] of DW1)
81        *       - Depth Stall ([13] of DW1)
82        *       - Post-Sync Operation ([13] of DW1)
83        *       - Render Target Cache Flush Enable ([12] of DW1)
84        *       - Notify Enable ([8] of DW1)"
85        *
86        * Because of the WAs above, we have to pick Stall at Pixel Scoreboard.
87        */
88       const uint32_t direct_wa = GEN6_PIPE_CONTROL_CS_STALL |
89                                  GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
90 
91       ilo_render_pipe_control(r, direct_wa);
92    }
93 
94    if (indirect_wa_cond &&
95        !(r->state.current_pipe_control_dw1 & GEN6_PIPE_CONTROL_WRITE__MASK)) {
96       const uint32_t indirect_wa = GEN6_PIPE_CONTROL_WRITE_IMM;
97 
98       ilo_render_pipe_control(r, indirect_wa);
99    }
100 }
101 
102 /**
103  * This should be called before any non-pipelined state command.
104  */
105 static void
gen6_wa_pre_non_pipelined(struct ilo_render * r)106 gen6_wa_pre_non_pipelined(struct ilo_render *r)
107 {
108    ILO_DEV_ASSERT(r->dev, 6, 6);
109 
110    /* non-pipelined state commands produce depth stall */
111    gen6_wa_pre_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
112 }
113 
114 static void
gen6_wa_post_3dstate_urb_no_gs(struct ilo_render * r)115 gen6_wa_post_3dstate_urb_no_gs(struct ilo_render *r)
116 {
117    /*
118     * From the Sandy Bridge PRM, volume 2 part 1, page 27:
119     *
120     *     "Because of a urb corruption caused by allocating a previous
121     *      gsunit's urb entry to vsunit software is required to send a
122     *      "GS NULL Fence" (Send URB fence with VS URB size == 1 and GS URB
123     *      size == 0) plus a dummy DRAW call before any case where VS will
124     *      be taking over GS URB space."
125     */
126    const uint32_t dw1 = GEN6_PIPE_CONTROL_CS_STALL;
127 
128    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
129       gen6_wa_pre_pipe_control(r, dw1);
130    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
131       ilo_render_pipe_control(r, dw1);
132 }
133 
134 static void
gen6_wa_post_3dstate_constant_vs(struct ilo_render * r)135 gen6_wa_post_3dstate_constant_vs(struct ilo_render *r)
136 {
137    /*
138     * According to upload_vs_state() of the classic driver, we need to emit a
139     * PIPE_CONTROL after 3DSTATE_CONSTANT_VS, otherwise the command is kept
140     * being buffered by VS FF, to the point that the FF dies.
141     */
142    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_STALL |
143                         GEN6_PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE |
144                         GEN6_PIPE_CONTROL_STATE_CACHE_INVALIDATE;
145 
146    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
147       gen6_wa_pre_pipe_control(r, dw1);
148    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
149       ilo_render_pipe_control(r, dw1);
150 }
151 
152 static void
gen6_wa_pre_3dstate_vs_toggle(struct ilo_render * r)153 gen6_wa_pre_3dstate_vs_toggle(struct ilo_render *r)
154 {
155    /*
156     * The classic driver has this undocumented WA:
157     *
158     * From the BSpec, 3D Pipeline > Geometry > Vertex Shader > State,
159     * 3DSTATE_VS, Dword 5.0 "VS Function Enable":
160     *
161     *   [DevSNB] A pipeline flush must be programmed prior to a 3DSTATE_VS
162     *   command that causes the VS Function Enable to toggle. Pipeline
163     *   flush can be executed by sending a PIPE_CONTROL command with CS
164     *   stall bit set and a post sync operation.
165     */
166    const uint32_t dw1 = GEN6_PIPE_CONTROL_WRITE_IMM |
167                         GEN6_PIPE_CONTROL_CS_STALL;
168 
169    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
170       gen6_wa_pre_pipe_control(r, dw1);
171    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
172       ilo_render_pipe_control(r, dw1);
173 }
174 
175 static void
gen6_wa_pre_3dstate_wm_max_threads(struct ilo_render * r)176 gen6_wa_pre_3dstate_wm_max_threads(struct ilo_render *r)
177 {
178    /*
179     * From the Sandy Bridge PRM, volume 2 part 1, page 274:
180     *
181     *     "A PIPE_CONTROL command, with only the Stall At Pixel Scoreboard
182     *      field set (DW1 Bit 1), must be issued prior to any change to the
183     *      value in this field (Maximum Number of Threads in 3DSTATE_WM)"
184     */
185    const uint32_t dw1 = GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
186 
187    ILO_DEV_ASSERT(r->dev, 6, 6);
188 
189    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
190       gen6_wa_pre_pipe_control(r, dw1);
191    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
192       ilo_render_pipe_control(r, dw1);
193 }
194 
195 static void
gen6_wa_pre_3dstate_multisample(struct ilo_render * r)196 gen6_wa_pre_3dstate_multisample(struct ilo_render *r)
197 {
198    /*
199     * From the Sandy Bridge PRM, volume 2 part 1, page 305:
200     *
201     *     "Driver must guarentee that all the caches in the depth pipe are
202     *      flushed before this command (3DSTATE_MULTISAMPLE) is parsed. This
203     *      requires driver to send a PIPE_CONTROL with a CS stall along with a
204     *      Depth Flush prior to this command."
205     */
206    const uint32_t dw1 = GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
207                         GEN6_PIPE_CONTROL_CS_STALL;
208 
209    ILO_DEV_ASSERT(r->dev, 6, 6);
210 
211    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
212       gen6_wa_pre_pipe_control(r, dw1);
213    if ((r->state.current_pipe_control_dw1 & dw1) != dw1)
214       ilo_render_pipe_control(r, dw1);
215 }
216 
217 static void
gen6_wa_pre_depth(struct ilo_render * r)218 gen6_wa_pre_depth(struct ilo_render *r)
219 {
220    ILO_DEV_ASSERT(r->dev, 6, 6);
221 
222    /*
223     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
224     *
225     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
226     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
227     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
228     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
229     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
230     *      Depth Flush Bit set, followed by another pipelined depth stall
231     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
232     *      guarantee that the pipeline from WM onwards is already flushed
233     *      (e.g., via a preceding MI_FLUSH)."
234     *
235     * According to the classic driver, it also applies for GEN6.
236     */
237    gen6_wa_pre_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL |
238                                GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
239 
240    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
241    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
242    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
243 }
244 
245 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
246 
247 void
gen6_draw_common_select(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)248 gen6_draw_common_select(struct ilo_render *r,
249                         const struct ilo_state_vector *vec,
250                         struct ilo_render_draw_session *session)
251 {
252    /* PIPELINE_SELECT */
253    if (r->hw_ctx_changed) {
254       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
255          gen6_wa_pre_non_pipelined(r);
256 
257       gen6_PIPELINE_SELECT(r->builder, 0x0);
258    }
259 }
260 
261 void
gen6_draw_common_sip(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)262 gen6_draw_common_sip(struct ilo_render *r,
263                      const struct ilo_state_vector *vec,
264                      struct ilo_render_draw_session *session)
265 {
266    /* STATE_SIP */
267    if (r->hw_ctx_changed) {
268       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
269          gen6_wa_pre_non_pipelined(r);
270 
271       gen6_STATE_SIP(r->builder, 0);
272    }
273 }
274 
275 void
gen6_draw_common_base_address(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)276 gen6_draw_common_base_address(struct ilo_render *r,
277                               const struct ilo_state_vector *vec,
278                               struct ilo_render_draw_session *session)
279 {
280    /* STATE_BASE_ADDRESS */
281    if (r->state_bo_changed || r->instruction_bo_changed ||
282        r->batch_bo_changed) {
283       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
284          gen6_wa_pre_non_pipelined(r);
285 
286       if (ilo_dev_gen(r->dev) >= ILO_GEN(8))
287          gen8_state_base_address(r->builder, r->hw_ctx_changed);
288       else
289          gen6_state_base_address(r->builder, r->hw_ctx_changed);
290 
291       /*
292        * From the Sandy Bridge PRM, volume 1 part 1, page 28:
293        *
294        *     "The following commands must be reissued following any change to
295        *      the base addresses:
296        *
297        *       * 3DSTATE_BINDING_TABLE_POINTERS
298        *       * 3DSTATE_SAMPLER_STATE_POINTERS
299        *       * 3DSTATE_VIEWPORT_STATE_POINTERS
300        *       * 3DSTATE_CC_POINTERS
301        *       * MEDIA_STATE_POINTERS"
302        *
303        * 3DSTATE_SCISSOR_STATE_POINTERS is not on the list, but it is
304        * reasonable to also reissue the command.  Same to PCB.
305        */
306       session->viewport_changed = true;
307 
308       session->scissor_changed = true;
309 
310       session->blend_changed = true;
311       session->dsa_changed = true;
312       session->cc_changed = true;
313 
314       session->sampler_vs_changed = true;
315       session->sampler_gs_changed = true;
316       session->sampler_fs_changed = true;
317 
318       session->pcb_vs_changed = true;
319       session->pcb_gs_changed = true;
320       session->pcb_fs_changed = true;
321 
322       session->binding_table_vs_changed = true;
323       session->binding_table_gs_changed = true;
324       session->binding_table_fs_changed = true;
325    }
326 }
327 
328 static void
gen6_draw_common_urb(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)329 gen6_draw_common_urb(struct ilo_render *r,
330                      const struct ilo_state_vector *vec,
331                      struct ilo_render_draw_session *session)
332 {
333    const bool gs_active = (vec->gs || (vec->vs &&
334             ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)));
335 
336    /* 3DSTATE_URB */
337    if (session->urb_delta.dirty & (ILO_STATE_URB_3DSTATE_URB_VS |
338                                    ILO_STATE_URB_3DSTATE_URB_GS)) {
339       gen6_3DSTATE_URB(r->builder, &vec->urb);
340 
341       if (r->state.gs.active && !gs_active)
342          gen6_wa_post_3dstate_urb_no_gs(r);
343    }
344 
345    r->state.gs.active = gs_active;
346 }
347 
348 static void
gen6_draw_common_pointers_1(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)349 gen6_draw_common_pointers_1(struct ilo_render *r,
350                             const struct ilo_state_vector *vec,
351                             struct ilo_render_draw_session *session)
352 {
353    /* 3DSTATE_VIEWPORT_STATE_POINTERS */
354    if (session->viewport_changed) {
355       gen6_3DSTATE_VIEWPORT_STATE_POINTERS(r->builder,
356             r->state.CLIP_VIEWPORT,
357             r->state.SF_VIEWPORT,
358             r->state.CC_VIEWPORT);
359    }
360 }
361 
362 static void
gen6_draw_common_pointers_2(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)363 gen6_draw_common_pointers_2(struct ilo_render *r,
364                             const struct ilo_state_vector *vec,
365                             struct ilo_render_draw_session *session)
366 {
367    /* 3DSTATE_CC_STATE_POINTERS */
368    if (session->blend_changed ||
369        session->dsa_changed ||
370        session->cc_changed) {
371       gen6_3DSTATE_CC_STATE_POINTERS(r->builder,
372             r->state.BLEND_STATE,
373             r->state.DEPTH_STENCIL_STATE,
374             r->state.COLOR_CALC_STATE);
375    }
376 
377    /* 3DSTATE_SAMPLER_STATE_POINTERS */
378    if (session->sampler_vs_changed ||
379        session->sampler_gs_changed ||
380        session->sampler_fs_changed) {
381       gen6_3DSTATE_SAMPLER_STATE_POINTERS(r->builder,
382             r->state.vs.SAMPLER_STATE,
383             0,
384             r->state.wm.SAMPLER_STATE);
385    }
386 }
387 
388 static void
gen6_draw_common_pointers_3(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)389 gen6_draw_common_pointers_3(struct ilo_render *r,
390                             const struct ilo_state_vector *vec,
391                             struct ilo_render_draw_session *session)
392 {
393    /* 3DSTATE_SCISSOR_STATE_POINTERS */
394    if (session->scissor_changed) {
395       gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
396             r->state.SCISSOR_RECT);
397    }
398 
399    /* 3DSTATE_BINDING_TABLE_POINTERS */
400    if (session->binding_table_vs_changed ||
401        session->binding_table_gs_changed ||
402        session->binding_table_fs_changed) {
403       gen6_3DSTATE_BINDING_TABLE_POINTERS(r->builder,
404             r->state.vs.BINDING_TABLE_STATE,
405             r->state.gs.BINDING_TABLE_STATE,
406             r->state.wm.BINDING_TABLE_STATE);
407    }
408 }
409 
410 void
gen6_draw_vf(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)411 gen6_draw_vf(struct ilo_render *r,
412              const struct ilo_state_vector *vec,
413              struct ilo_render_draw_session *session)
414 {
415    if (ilo_dev_gen(r->dev) >= ILO_GEN(7.5)) {
416       /* 3DSTATE_INDEX_BUFFER */
417       if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
418           DIRTY(IB) || r->batch_bo_changed)
419          gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
420 
421       /* 3DSTATE_VF */
422       if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF)
423          gen75_3DSTATE_VF(r->builder, &vec->ve->vf);
424    } else {
425       /* 3DSTATE_INDEX_BUFFER */
426       if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
427           DIRTY(IB) || r->batch_bo_changed)
428          gen6_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
429    }
430 
431    /* 3DSTATE_VERTEX_BUFFERS */
432    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
433        DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
434       gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
435             vec->vb.vb, vec->ve->vb_count);
436    }
437 
438    /* 3DSTATE_VERTEX_ELEMENTS */
439    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS)
440       gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf);
441 }
442 
443 void
gen6_draw_vf_statistics(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)444 gen6_draw_vf_statistics(struct ilo_render *r,
445                         const struct ilo_state_vector *vec,
446                         struct ilo_render_draw_session *session)
447 {
448    /* 3DSTATE_VF_STATISTICS */
449    if (r->hw_ctx_changed)
450       gen6_3DSTATE_VF_STATISTICS(r->builder, false);
451 }
452 
453 void
gen6_draw_vs(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)454 gen6_draw_vs(struct ilo_render *r,
455              const struct ilo_state_vector *vec,
456              struct ilo_render_draw_session *session)
457 {
458    /* 3DSTATE_CONSTANT_VS */
459    if (session->pcb_vs_changed) {
460       gen6_3DSTATE_CONSTANT_VS(r->builder,
461             &r->state.vs.PUSH_CONSTANT_BUFFER,
462             &r->state.vs.PUSH_CONSTANT_BUFFER_size,
463             1);
464 
465       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
466          gen6_wa_post_3dstate_constant_vs(r);
467    }
468 
469    /* 3DSTATE_VS */
470    if (DIRTY(VS) || r->instruction_bo_changed) {
471       const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->vs);
472       const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->vs);
473 
474       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
475          gen6_wa_pre_3dstate_vs_toggle(r);
476 
477       if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
478           ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
479          gen6_3DSTATE_VS(r->builder, &cso->vs_sol.vs,
480                kernel_offset, r->vs_scratch.bo);
481       } else {
482          gen6_3DSTATE_VS(r->builder, &cso->vs,
483                kernel_offset, r->vs_scratch.bo);
484       }
485    }
486 }
487 
488 static void
gen6_draw_gs(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)489 gen6_draw_gs(struct ilo_render *r,
490              const struct ilo_state_vector *vec,
491              struct ilo_render_draw_session *session)
492 {
493    /* 3DSTATE_CONSTANT_GS */
494    if (session->pcb_gs_changed)
495       gen6_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
496 
497    /* 3DSTATE_GS */
498    if (DIRTY(GS) || DIRTY(VS) ||
499        session->prim_changed || r->instruction_bo_changed) {
500       const union ilo_shader_cso *cso;
501       uint32_t kernel_offset;
502 
503       if (vec->gs) {
504          cso = ilo_shader_get_kernel_cso(vec->gs);
505          kernel_offset = ilo_shader_get_kernel_offset(vec->gs);
506 
507          gen6_3DSTATE_GS(r->builder, &cso->gs,
508                kernel_offset, r->gs_scratch.bo);
509       } else if (ilo_dev_gen(r->dev) == ILO_GEN(6) &&
510             ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_GEN6_SO)) {
511          const int verts_per_prim =
512             u_vertices_per_prim(session->reduced_prim);
513          enum ilo_kernel_param param;
514 
515          switch (verts_per_prim) {
516          case 1:
517             param = ILO_KERNEL_VS_GEN6_SO_POINT_OFFSET;
518             break;
519          case 2:
520             param = ILO_KERNEL_VS_GEN6_SO_LINE_OFFSET;
521             break;
522          default:
523             param = ILO_KERNEL_VS_GEN6_SO_TRI_OFFSET;
524             break;
525          }
526 
527          cso = ilo_shader_get_kernel_cso(vec->vs);
528          kernel_offset = ilo_shader_get_kernel_offset(vec->vs) +
529             ilo_shader_get_kernel_param(vec->vs, param);
530 
531          gen6_3DSTATE_GS(r->builder, &cso->vs_sol.sol,
532                kernel_offset, r->gs_scratch.bo);
533       } else {
534          gen6_3DSTATE_GS(r->builder, &vec->disabled_gs, 0, NULL);
535       }
536    }
537 }
538 
539 static bool
gen6_draw_update_max_svbi(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)540 gen6_draw_update_max_svbi(struct ilo_render *r,
541                           const struct ilo_state_vector *vec,
542                           struct ilo_render_draw_session *session)
543 {
544    if (DIRTY(VS) || DIRTY(GS) || DIRTY(SO)) {
545       const struct pipe_stream_output_info *so_info =
546          (vec->gs) ? ilo_shader_get_kernel_so_info(vec->gs) :
547          (vec->vs) ? ilo_shader_get_kernel_so_info(vec->vs) : NULL;
548       unsigned max_svbi = 0xffffffff;
549       int i;
550 
551       for (i = 0; i < so_info->num_outputs; i++) {
552          const int output_buffer = so_info->output[i].output_buffer;
553          const struct pipe_stream_output_target *so =
554             vec->so.states[output_buffer];
555          const int struct_size = so_info->stride[output_buffer] * 4;
556          const int elem_size = so_info->output[i].num_components * 4;
557          int buf_size, count;
558 
559          if (!so) {
560             max_svbi = 0;
561             break;
562          }
563 
564          buf_size = so->buffer_size - so_info->output[i].dst_offset * 4;
565 
566          count = buf_size / struct_size;
567          if (buf_size % struct_size >= elem_size)
568             count++;
569 
570          if (count < max_svbi)
571             max_svbi = count;
572       }
573 
574       if (r->state.so_max_vertices != max_svbi) {
575          r->state.so_max_vertices = max_svbi;
576          return true;
577       }
578    }
579 
580    return false;
581 }
582 
583 static void
gen6_draw_gs_svbi(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)584 gen6_draw_gs_svbi(struct ilo_render *r,
585                   const struct ilo_state_vector *vec,
586                   struct ilo_render_draw_session *session)
587 {
588    const bool emit = gen6_draw_update_max_svbi(r, vec, session);
589 
590    /* 3DSTATE_GS_SVB_INDEX */
591    if (emit) {
592       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
593          gen6_wa_pre_non_pipelined(r);
594 
595       gen6_3DSTATE_GS_SVB_INDEX(r->builder,
596             0, 0, r->state.so_max_vertices,
597             false);
598 
599       if (r->hw_ctx_changed) {
600          int i;
601 
602          /*
603           * From the Sandy Bridge PRM, volume 2 part 1, page 148:
604           *
605           *     "If a buffer is not enabled then the SVBI must be set to 0x0
606           *      in order to not cause overflow in that SVBI."
607           *
608           *     "If a buffer is not enabled then the MaxSVBI must be set to
609           *      0xFFFFFFFF in order to not cause overflow in that SVBI."
610           */
611          for (i = 1; i < 4; i++) {
612             gen6_3DSTATE_GS_SVB_INDEX(r->builder,
613                   i, 0, 0xffffffff, false);
614          }
615       }
616    }
617 }
618 
619 void
gen6_draw_clip(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)620 gen6_draw_clip(struct ilo_render *r,
621                const struct ilo_state_vector *vec,
622                struct ilo_render_draw_session *session)
623 {
624    /* 3DSTATE_CLIP */
625    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_CLIP)
626       gen6_3DSTATE_CLIP(r->builder, &vec->rasterizer->rs);
627 }
628 
629 static void
gen6_draw_sf(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)630 gen6_draw_sf(struct ilo_render *r,
631              const struct ilo_state_vector *vec,
632              struct ilo_render_draw_session *session)
633 {
634    /* 3DSTATE_SF */
635    if ((session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF) || DIRTY(FS)) {
636       const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
637       gen6_3DSTATE_SF(r->builder, &vec->rasterizer->rs, sbe);
638    }
639 }
640 
641 void
gen6_draw_sf_rect(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)642 gen6_draw_sf_rect(struct ilo_render *r,
643                   const struct ilo_state_vector *vec,
644                   struct ilo_render_draw_session *session)
645 {
646    /* 3DSTATE_DRAWING_RECTANGLE */
647    if (DIRTY(FB)) {
648       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
649          gen6_wa_pre_non_pipelined(r);
650 
651       gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
652             vec->fb.state.width, vec->fb.state.height);
653    }
654 }
655 
656 static void
gen6_draw_wm(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)657 gen6_draw_wm(struct ilo_render *r,
658              const struct ilo_state_vector *vec,
659              struct ilo_render_draw_session *session)
660 {
661    /* 3DSTATE_CONSTANT_PS */
662    if (session->pcb_fs_changed) {
663       gen6_3DSTATE_CONSTANT_PS(r->builder,
664             &r->state.wm.PUSH_CONSTANT_BUFFER,
665             &r->state.wm.PUSH_CONSTANT_BUFFER_size,
666             1);
667    }
668 
669    /* 3DSTATE_WM */
670    if (DIRTY(FS) ||
671        (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM) ||
672        r->instruction_bo_changed) {
673       const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
674       const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
675 
676       if (ilo_dev_gen(r->dev) == ILO_GEN(6) && r->hw_ctx_changed)
677          gen6_wa_pre_3dstate_wm_max_threads(r);
678 
679       gen6_3DSTATE_WM(r->builder, &vec->rasterizer->rs,
680             &cso->ps, kernel_offset, r->fs_scratch.bo);
681    }
682 }
683 
684 static void
gen6_draw_wm_multisample(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)685 gen6_draw_wm_multisample(struct ilo_render *r,
686                          const struct ilo_state_vector *vec,
687                          struct ilo_render_draw_session *session)
688 {
689    /* 3DSTATE_MULTISAMPLE */
690    if (DIRTY(FB) || (session->rs_delta.dirty &
691             ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
692       const uint8_t sample_count = (vec->fb.num_samples > 1) ? 4 : 1;
693 
694       if (ilo_dev_gen(r->dev) == ILO_GEN(6)) {
695          gen6_wa_pre_non_pipelined(r);
696          gen6_wa_pre_3dstate_multisample(r);
697       }
698 
699       gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
700             &r->sample_pattern, sample_count);
701    }
702 
703    /* 3DSTATE_SAMPLE_MASK */
704    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
705       gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
706 }
707 
708 static void
gen6_draw_wm_depth(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)709 gen6_draw_wm_depth(struct ilo_render *r,
710                    const struct ilo_state_vector *vec,
711                    struct ilo_render_draw_session *session)
712 {
713    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
714    if (DIRTY(FB) || r->batch_bo_changed) {
715       const struct ilo_state_zs *zs;
716       uint32_t clear_params;
717 
718       if (vec->fb.state.zsbuf) {
719          const struct ilo_surface_cso *surface =
720             (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
721          const struct ilo_texture_slice *slice =
722             ilo_texture_get_slice(ilo_texture(surface->base.texture),
723                   surface->base.u.tex.level, surface->base.u.tex.first_layer);
724 
725          assert(!surface->is_rt);
726 
727          zs = &surface->u.zs;
728          clear_params = slice->clear_value;
729       }
730       else {
731          zs = &vec->fb.null_zs;
732          clear_params = 0;
733       }
734 
735       if (ilo_dev_gen(r->dev) == ILO_GEN(6)) {
736          gen6_wa_pre_non_pipelined(r);
737          gen6_wa_pre_depth(r);
738       }
739 
740       gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
741       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
742       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
743       gen6_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
744    }
745 }
746 
747 void
gen6_draw_wm_raster(struct ilo_render * r,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)748 gen6_draw_wm_raster(struct ilo_render *r,
749                     const struct ilo_state_vector *vec,
750                     struct ilo_render_draw_session *session)
751 {
752    /* 3DSTATE_POLY_STIPPLE_PATTERN and 3DSTATE_POLY_STIPPLE_OFFSET */
753    if ((DIRTY(RASTERIZER) || DIRTY(POLY_STIPPLE)) &&
754        vec->rasterizer->state.poly_stipple_enable) {
755       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
756          gen6_wa_pre_non_pipelined(r);
757 
758       gen6_3DSTATE_POLY_STIPPLE_PATTERN(r->builder, &vec->poly_stipple);
759       gen6_3DSTATE_POLY_STIPPLE_OFFSET(r->builder, &vec->poly_stipple);
760    }
761 
762    /* 3DSTATE_LINE_STIPPLE */
763    if (DIRTY(RASTERIZER) && vec->rasterizer->state.line_stipple_enable) {
764       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
765          gen6_wa_pre_non_pipelined(r);
766 
767       gen6_3DSTATE_LINE_STIPPLE(r->builder, &vec->line_stipple);
768    }
769 
770    /* 3DSTATE_AA_LINE_PARAMETERS */
771    if (session->rs_delta.dirty &
772          ILO_STATE_RASTER_3DSTATE_AA_LINE_PARAMETERS) {
773       if (ilo_dev_gen(r->dev) == ILO_GEN(6))
774          gen6_wa_pre_non_pipelined(r);
775 
776       gen6_3DSTATE_AA_LINE_PARAMETERS(r->builder, &vec->rasterizer->rs);
777    }
778 }
779 
780 #undef DIRTY
781 
782 void
ilo_render_emit_draw_commands_gen6(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)783 ilo_render_emit_draw_commands_gen6(struct ilo_render *render,
784                                    const struct ilo_state_vector *vec,
785                                    struct ilo_render_draw_session *session)
786 {
787    ILO_DEV_ASSERT(render->dev, 6, 6);
788 
789    /*
790     * We try to keep the order of the commands match, as closely as possible,
791     * that of the classic i965 driver.  It allows us to compare the command
792     * streams easily.
793     */
794    gen6_draw_common_select(render, vec, session);
795    gen6_draw_gs_svbi(render, vec, session);
796    gen6_draw_common_sip(render, vec, session);
797    gen6_draw_vf_statistics(render, vec, session);
798    gen6_draw_common_base_address(render, vec, session);
799    gen6_draw_common_pointers_1(render, vec, session);
800    gen6_draw_common_urb(render, vec, session);
801    gen6_draw_common_pointers_2(render, vec, session);
802    gen6_draw_wm_multisample(render, vec, session);
803    gen6_draw_vs(render, vec, session);
804    gen6_draw_gs(render, vec, session);
805    gen6_draw_clip(render, vec, session);
806    gen6_draw_sf(render, vec, session);
807    gen6_draw_wm(render, vec, session);
808    gen6_draw_common_pointers_3(render, vec, session);
809    gen6_draw_wm_depth(render, vec, session);
810    gen6_draw_wm_raster(render, vec, session);
811    gen6_draw_sf_rect(render, vec, session);
812    gen6_draw_vf(render, vec, session);
813 
814    ilo_render_3dprimitive(render, &vec->draw_info);
815 }
816 
817 static void
gen6_rectlist_vs_to_sf(struct ilo_render * r,const struct ilo_blitter * blitter)818 gen6_rectlist_vs_to_sf(struct ilo_render *r,
819                        const struct ilo_blitter *blitter)
820 {
821    gen6_3DSTATE_CONSTANT_VS(r->builder, NULL, NULL, 0);
822    gen6_wa_post_3dstate_constant_vs(r);
823 
824    gen6_wa_pre_3dstate_vs_toggle(r);
825    gen6_3DSTATE_VS(r->builder, &blitter->vs, 0, NULL);
826 
827    gen6_3DSTATE_CONSTANT_GS(r->builder, NULL, NULL, 0);
828    gen6_3DSTATE_GS(r->builder, &blitter->gs, 0, NULL);
829 
830    gen6_3DSTATE_CLIP(r->builder, &blitter->fb.rs);
831    gen6_3DSTATE_SF(r->builder, &blitter->fb.rs, &blitter->sbe);
832 }
833 
834 static void
gen6_rectlist_wm(struct ilo_render * r,const struct ilo_blitter * blitter)835 gen6_rectlist_wm(struct ilo_render *r,
836                  const struct ilo_blitter *blitter)
837 {
838    gen6_3DSTATE_CONSTANT_PS(r->builder, NULL, NULL, 0);
839 
840    gen6_wa_pre_3dstate_wm_max_threads(r);
841    gen6_3DSTATE_WM(r->builder, &blitter->fb.rs, &blitter->ps, 0, NULL);
842 }
843 
844 static void
gen6_rectlist_wm_depth(struct ilo_render * r,const struct ilo_blitter * blitter)845 gen6_rectlist_wm_depth(struct ilo_render *r,
846                        const struct ilo_blitter *blitter)
847 {
848    gen6_wa_pre_depth(r);
849 
850    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
851                         ILO_BLITTER_USE_FB_STENCIL))
852       gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
853 
854    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
855       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
856             &blitter->fb.dst.u.zs);
857    }
858 
859    if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
860       gen6_3DSTATE_STENCIL_BUFFER(r->builder,
861             &blitter->fb.dst.u.zs);
862    }
863 
864    gen6_3DSTATE_CLEAR_PARAMS(r->builder,
865          blitter->depth_clear_value);
866 }
867 
868 static void
gen6_rectlist_wm_multisample(struct ilo_render * r,const struct ilo_blitter * blitter)869 gen6_rectlist_wm_multisample(struct ilo_render *r,
870                              const struct ilo_blitter *blitter)
871 {
872    const uint8_t sample_count = (blitter->fb.num_samples > 1) ? 4 : 1;
873 
874    gen6_wa_pre_3dstate_multisample(r);
875 
876    gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs, &r->sample_pattern, sample_count);
877    gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
878 }
879 
880 int
ilo_render_get_rectlist_commands_len_gen6(const struct ilo_render * render,const struct ilo_blitter * blitter)881 ilo_render_get_rectlist_commands_len_gen6(const struct ilo_render *render,
882                                           const struct ilo_blitter *blitter)
883 {
884    ILO_DEV_ASSERT(render->dev, 6, 7.5);
885 
886    return 256;
887 }
888 
889 void
ilo_render_emit_rectlist_commands_gen6(struct ilo_render * r,const struct ilo_blitter * blitter,const struct ilo_render_rectlist_session * session)890 ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r,
891                                        const struct ilo_blitter *blitter,
892                                        const struct ilo_render_rectlist_session *session)
893 {
894    ILO_DEV_ASSERT(r->dev, 6, 6);
895 
896    gen6_wa_pre_non_pipelined(r);
897 
898    gen6_rectlist_wm_multisample(r, blitter);
899 
900    gen6_state_base_address(r->builder, true);
901 
902    gen6_user_3DSTATE_VERTEX_BUFFERS(r->builder,
903          session->vb_start, session->vb_end,
904          sizeof(blitter->vertices[0]));
905 
906    gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &blitter->vf);
907 
908    gen6_3DSTATE_URB(r->builder, &blitter->urb);
909 
910    if (r->state.gs.active) {
911       gen6_wa_post_3dstate_urb_no_gs(r);
912       r->state.gs.active = false;
913    }
914 
915    if (blitter->uses &
916        (ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_CC)) {
917       gen6_3DSTATE_CC_STATE_POINTERS(r->builder, 0,
918             r->state.DEPTH_STENCIL_STATE, r->state.COLOR_CALC_STATE);
919    }
920 
921    gen6_rectlist_vs_to_sf(r, blitter);
922    gen6_rectlist_wm(r, blitter);
923 
924    if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) {
925       gen6_3DSTATE_VIEWPORT_STATE_POINTERS(r->builder,
926             0, 0, r->state.CC_VIEWPORT);
927    }
928 
929    gen6_rectlist_wm_depth(r, blitter);
930 
931    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
932          blitter->fb.width, blitter->fb.height);
933 
934    ilo_render_3dprimitive(r, &blitter->draw_info);
935 }
936 
937 int
ilo_render_get_draw_commands_len_gen6(const struct ilo_render * render,const struct ilo_state_vector * vec)938 ilo_render_get_draw_commands_len_gen6(const struct ilo_render *render,
939                                       const struct ilo_state_vector *vec)
940 {
941    static int len;
942 
943    ILO_DEV_ASSERT(render->dev, 6, 6);
944 
945    if (!len) {
946       len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 3;
947       len += GEN6_3DSTATE_GS_SVB_INDEX__SIZE * 4;
948       len += GEN6_PIPE_CONTROL__SIZE * 5;
949 
950       len +=
951          GEN6_STATE_BASE_ADDRESS__SIZE +
952          GEN6_STATE_SIP__SIZE +
953          GEN6_3DSTATE_VF_STATISTICS__SIZE +
954          GEN6_PIPELINE_SELECT__SIZE +
955          GEN6_3DSTATE_BINDING_TABLE_POINTERS__SIZE +
956          GEN6_3DSTATE_SAMPLER_STATE_POINTERS__SIZE +
957          GEN6_3DSTATE_URB__SIZE +
958          GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
959          GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
960          GEN6_3DSTATE_INDEX_BUFFER__SIZE +
961          GEN6_3DSTATE_VIEWPORT_STATE_POINTERS__SIZE +
962          GEN6_3DSTATE_CC_STATE_POINTERS__SIZE +
963          GEN6_3DSTATE_SCISSOR_STATE_POINTERS__SIZE +
964          GEN6_3DSTATE_VS__SIZE +
965          GEN6_3DSTATE_GS__SIZE +
966          GEN6_3DSTATE_CLIP__SIZE +
967          GEN6_3DSTATE_SF__SIZE +
968          GEN6_3DSTATE_WM__SIZE +
969          GEN6_3DSTATE_SAMPLE_MASK__SIZE +
970          GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
971          GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
972          GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
973          GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
974          GEN6_3DSTATE_LINE_STIPPLE__SIZE +
975          GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
976          GEN6_3DSTATE_MULTISAMPLE__SIZE +
977          GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
978          GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
979          GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
980          GEN6_3DPRIMITIVE__SIZE;
981    }
982 
983    return len;
984 }
985