1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2012-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 #ifndef ILO_RENDER_GEN_H
29 #define ILO_RENDER_GEN_H
30 
31 #include "core/ilo_builder.h"
32 #include "core/ilo_builder_3d.h"
33 #include "core/ilo_builder_render.h"
34 #include "core/ilo_state_raster.h"
35 
36 #include "ilo_common.h"
37 #include "ilo_state.h"
38 #include "ilo_render.h"
39 
40 struct ilo_bo;
41 struct ilo_blitter;
42 struct ilo_render;
43 struct ilo_state_vector;
44 
45 /**
46  * Render Engine.
47  */
48 struct ilo_render {
49    const struct ilo_dev *dev;
50    struct ilo_builder *builder;
51 
52    struct intel_bo *workaround_bo;
53 
54    struct ilo_render_scratch_space {
55       struct intel_bo *bo;
56       int size;
57    } vs_scratch, gs_scratch, fs_scratch;
58 
59    struct ilo_state_sample_pattern sample_pattern;
60 
61    bool hw_ctx_changed;
62 
63    /*
64     * Any state that involves resources needs to be re-emitted when the
65     * batch bo changed.  This is because we do not pin the resources and
66     * their offsets (or existence) may change between batch buffers.
67     */
68    bool batch_bo_changed;
69    bool state_bo_changed;
70    bool instruction_bo_changed;
71 
72    /**
73     * HW states.
74     */
75    struct ilo_render_state {
76       /*
77        * When a WA is needed before some command, we always emit the WA right
78        * before the command.  Knowing what have already been done since last
79        * 3DPRIMITIVE allows us to skip some WAs.
80        */
81       uint32_t current_pipe_control_dw1;
82 
83       /*
84        * When a WA is needed after some command, we may have the WA follow the
85        * command immediately or defer it.  If this is non-zero, a PIPE_CONTROL
86        * will be emitted before 3DPRIMITIVE.
87        */
88       uint32_t deferred_pipe_control_dw1;
89 
90       int reduced_prim;
91       int so_max_vertices;
92 
93       struct ilo_state_urb urb;
94       struct ilo_state_raster rs;
95       struct ilo_state_cc cc;
96 
97       uint32_t SF_VIEWPORT;
98       uint32_t CLIP_VIEWPORT;
99       uint32_t SF_CLIP_VIEWPORT; /* GEN7+ */
100       uint32_t CC_VIEWPORT;
101 
102       uint32_t COLOR_CALC_STATE;
103       uint32_t BLEND_STATE;
104       uint32_t DEPTH_STENCIL_STATE;
105 
106       uint32_t SCISSOR_RECT;
107 
108       struct {
109          uint32_t BINDING_TABLE_STATE;
110          uint32_t SURFACE_STATE[ILO_MAX_SURFACES];
111          uint32_t SAMPLER_STATE;
112          uint32_t SAMPLER_BORDER_COLOR_STATE[ILO_MAX_SAMPLERS];
113          uint32_t PUSH_CONSTANT_BUFFER;
114          int PUSH_CONSTANT_BUFFER_size;
115       } vs;
116 
117       struct {
118          uint32_t BINDING_TABLE_STATE;
119          uint32_t SURFACE_STATE[ILO_MAX_SURFACES];
120          bool active;
121       } gs;
122 
123       struct {
124          uint32_t BINDING_TABLE_STATE;
125          uint32_t SURFACE_STATE[ILO_MAX_SURFACES];
126          uint32_t SAMPLER_STATE;
127          uint32_t SAMPLER_BORDER_COLOR_STATE[ILO_MAX_SAMPLERS];
128          uint32_t PUSH_CONSTANT_BUFFER;
129          int PUSH_CONSTANT_BUFFER_size;
130       } wm;
131 
132       struct {
133          uint32_t BINDING_TABLE_STATE;
134          uint32_t SURFACE_STATE[ILO_MAX_SURFACES];
135          uint32_t SAMPLER_STATE;
136          uint32_t SAMPLER_BORDER_COLOR_STATE[ILO_MAX_SAMPLERS];
137          uint32_t PUSH_CONSTANT_BUFFER;
138          int PUSH_CONSTANT_BUFFER_size;
139       } cs;
140    } state;
141 };
142 
143 struct ilo_render_draw_session {
144    uint32_t pipe_dirty;
145 
146    /* commands */
147    int reduced_prim;
148 
149    bool prim_changed;
150 
151    struct ilo_state_urb_delta urb_delta;
152    struct ilo_state_vf_delta vf_delta;
153    struct ilo_state_raster_delta rs_delta;
154    struct ilo_state_viewport_delta vp_delta;
155    struct ilo_state_cc_delta cc_delta;
156 
157    /* dynamic states */
158    bool viewport_changed;
159    bool scissor_changed;
160 
161    bool cc_changed;
162    bool dsa_changed;
163    bool blend_changed;
164 
165    bool sampler_vs_changed;
166    bool sampler_gs_changed;
167    bool sampler_fs_changed;
168 
169    bool pcb_vs_changed;
170    bool pcb_gs_changed;
171    bool pcb_fs_changed;
172 
173    /* surface states */
174    bool binding_table_vs_changed;
175    bool binding_table_gs_changed;
176    bool binding_table_fs_changed;
177 };
178 
179 struct ilo_render_rectlist_session {
180    uint32_t vb_start;
181    uint32_t vb_end;
182 };
183 
184 struct ilo_render_launch_grid_session {
185    const unsigned *thread_group_offset;
186    const unsigned *thread_group_dim;
187    unsigned thread_group_size;
188    const struct pipe_constant_buffer *input;
189    uint32_t pc;
190 
191    uint32_t idrt;
192    int idrt_size;
193 
194    uint32_t compute_data[6];
195    struct ilo_state_compute compute;
196 };
197 
198 int
199 ilo_render_get_draw_commands_len_gen6(const struct ilo_render *render,
200                                       const struct ilo_state_vector *vec);
201 
202 int
203 ilo_render_get_draw_commands_len_gen7(const struct ilo_render *render,
204                                       const struct ilo_state_vector *vec);
205 
206 int
207 ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
208                                       const struct ilo_state_vector *vec);
209 
210 static inline int
ilo_render_get_draw_commands_len(const struct ilo_render * render,const struct ilo_state_vector * vec)211 ilo_render_get_draw_commands_len(const struct ilo_render *render,
212                                  const struct ilo_state_vector *vec)
213 {
214    if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
215       return ilo_render_get_draw_commands_len_gen8(render, vec);
216    else if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
217       return ilo_render_get_draw_commands_len_gen7(render, vec);
218    else
219       return ilo_render_get_draw_commands_len_gen6(render, vec);
220 }
221 
222 void
223 ilo_render_emit_draw_commands_gen6(struct ilo_render *render,
224                                    const struct ilo_state_vector *vec,
225                                    struct ilo_render_draw_session *session);
226 
227 void
228 ilo_render_emit_draw_commands_gen7(struct ilo_render *render,
229                                    const struct ilo_state_vector *vec,
230                                    struct ilo_render_draw_session *session);
231 
232 void
233 ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
234                                    const struct ilo_state_vector *vec,
235                                    struct ilo_render_draw_session *session);
236 
237 static inline void
ilo_render_emit_draw_commands(struct ilo_render * render,const struct ilo_state_vector * vec,struct ilo_render_draw_session * session)238 ilo_render_emit_draw_commands(struct ilo_render *render,
239                               const struct ilo_state_vector *vec,
240                               struct ilo_render_draw_session *session)
241 {
242    const unsigned batch_used = ilo_builder_batch_used(render->builder);
243 
244    if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
245       ilo_render_emit_draw_commands_gen8(render, vec, session);
246    else if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
247       ilo_render_emit_draw_commands_gen7(render, vec, session);
248    else
249       ilo_render_emit_draw_commands_gen6(render, vec, session);
250 
251    assert(ilo_builder_batch_used(render->builder) <= batch_used +
252          ilo_render_get_draw_commands_len(render, vec));
253 }
254 
255 int
256 ilo_render_get_rectlist_commands_len_gen6(const struct ilo_render *render,
257                                           const struct ilo_blitter *blitter);
258 
259 int
260 ilo_render_get_rectlist_commands_len_gen8(const struct ilo_render *render,
261                                           const struct ilo_blitter *blitter);
262 
263 static inline int
ilo_render_get_rectlist_commands_len(const struct ilo_render * render,const struct ilo_blitter * blitter)264 ilo_render_get_rectlist_commands_len(const struct ilo_render *render,
265                                      const struct ilo_blitter *blitter)
266 {
267    if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
268       return ilo_render_get_rectlist_commands_len_gen8(render, blitter);
269    else
270       return ilo_render_get_rectlist_commands_len_gen6(render, blitter);
271 }
272 
273 void
274 ilo_render_emit_rectlist_commands_gen6(struct ilo_render *r,
275                                        const struct ilo_blitter *blitter,
276                                        const struct ilo_render_rectlist_session *session);
277 
278 void
279 ilo_render_emit_rectlist_commands_gen7(struct ilo_render *r,
280                                        const struct ilo_blitter *blitter,
281                                        const struct ilo_render_rectlist_session *session);
282 
283 void
284 ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
285                                        const struct ilo_blitter *blitter,
286                                        const struct ilo_render_rectlist_session *session);
287 
288 static inline void
ilo_render_emit_rectlist_commands(struct ilo_render * render,const struct ilo_blitter * blitter,const struct ilo_render_rectlist_session * session)289 ilo_render_emit_rectlist_commands(struct ilo_render *render,
290                                   const struct ilo_blitter *blitter,
291                                   const struct ilo_render_rectlist_session *session)
292 {
293    const unsigned batch_used = ilo_builder_batch_used(render->builder);
294 
295    if (ilo_dev_gen(render->dev) >= ILO_GEN(8))
296       ilo_render_emit_rectlist_commands_gen8(render, blitter, session);
297    else if (ilo_dev_gen(render->dev) >= ILO_GEN(7))
298       ilo_render_emit_rectlist_commands_gen7(render, blitter, session);
299    else
300       ilo_render_emit_rectlist_commands_gen6(render, blitter, session);
301 
302    assert(ilo_builder_batch_used(render->builder) <= batch_used +
303          ilo_render_get_rectlist_commands_len(render, blitter));
304 }
305 
306 int
307 ilo_render_get_launch_grid_commands_len(const struct ilo_render *render,
308                                         const struct ilo_state_vector *vec);
309 
310 void
311 ilo_render_emit_launch_grid_commands(struct ilo_render *render,
312                                      const struct ilo_state_vector *vec,
313                                      const struct ilo_render_launch_grid_session *session);
314 
315 int
316 ilo_render_get_draw_dynamic_states_len(const struct ilo_render *render,
317                                        const struct ilo_state_vector *vec);
318 
319 void
320 ilo_render_emit_draw_dynamic_states(struct ilo_render *render,
321                                     const struct ilo_state_vector *vec,
322                                     struct ilo_render_draw_session *session);
323 
324 int
325 ilo_render_get_rectlist_dynamic_states_len(const struct ilo_render *render,
326                                            const struct ilo_blitter *blitter);
327 
328 void
329 ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render,
330                                         const struct ilo_blitter *blitter,
331                                         struct ilo_render_rectlist_session *session);
332 
333 int
334 ilo_render_get_launch_grid_dynamic_states_len(const struct ilo_render *render,
335                                               const struct ilo_state_vector *vec);
336 
337 void
338 ilo_render_emit_launch_grid_dynamic_states(struct ilo_render *render,
339                                            const struct ilo_state_vector *vec,
340                                            struct ilo_render_launch_grid_session *session);
341 
342 int
343 ilo_render_get_draw_surface_states_len(const struct ilo_render *render,
344                                        const struct ilo_state_vector *vec);
345 
346 void
347 ilo_render_emit_draw_surface_states(struct ilo_render *render,
348                                     const struct ilo_state_vector *vec,
349                                     struct ilo_render_draw_session *session);
350 
351 int
352 ilo_render_get_launch_grid_surface_states_len(const struct ilo_render *render,
353                                               const struct ilo_state_vector *vec);
354 
355 void
356 ilo_render_emit_launch_grid_surface_states(struct ilo_render *render,
357                                            const struct ilo_state_vector *vec,
358                                            struct ilo_render_launch_grid_session *session);
359 
360 /**
361  * A convenient wrapper for gen6_PIPE_CONTROL().  This should be enough for
362  * our needs everywhere except for queries.
363  */
364 static inline void
ilo_render_pipe_control(struct ilo_render * r,uint32_t dw1)365 ilo_render_pipe_control(struct ilo_render *r, uint32_t dw1)
366 {
367    const uint32_t write_mask = (dw1 & GEN6_PIPE_CONTROL_WRITE__MASK);
368    struct intel_bo *bo = (write_mask) ? r->workaround_bo : NULL;
369 
370    ILO_DEV_ASSERT(r->dev, 6, 8);
371 
372    if (write_mask)
373       assert(write_mask == GEN6_PIPE_CONTROL_WRITE_IMM);
374 
375    if (dw1 & GEN6_PIPE_CONTROL_CS_STALL) {
376       /* CS stall cannot be set alone */
377       const uint32_t mask = GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH |
378                             GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH |
379                             GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL |
380                             GEN6_PIPE_CONTROL_DEPTH_STALL |
381                             GEN6_PIPE_CONTROL_WRITE__MASK;
382       if (!(dw1 & mask))
383          dw1 |= GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL;
384    }
385 
386    gen6_PIPE_CONTROL(r->builder, dw1, bo, 0, 0);
387 
388    r->state.current_pipe_control_dw1 |= dw1;
389    r->state.deferred_pipe_control_dw1 &= ~dw1;
390 }
391 
392 /**
393  * A convenient wrapper for gen{6,7}_3DPRIMITIVE().
394  */
395 static inline void
ilo_render_3dprimitive(struct ilo_render * r,const struct gen6_3dprimitive_info * info)396 ilo_render_3dprimitive(struct ilo_render *r,
397                        const struct gen6_3dprimitive_info *info)
398 {
399    ILO_DEV_ASSERT(r->dev, 6, 8);
400 
401    if (r->state.deferred_pipe_control_dw1)
402       ilo_render_pipe_control(r, r->state.deferred_pipe_control_dw1);
403 
404    /* 3DPRIMITIVE */
405    if (ilo_dev_gen(r->dev) >= ILO_GEN(7))
406       gen7_3DPRIMITIVE(r->builder, info);
407    else
408       gen6_3DPRIMITIVE(r->builder, info);
409 
410    r->state.current_pipe_control_dw1 = 0;
411    assert(!r->state.deferred_pipe_control_dw1);
412 }
413 
414 void
415 gen6_wa_pre_pipe_control(struct ilo_render *r, uint32_t dw1);
416 
417 void
418 gen6_draw_common_select(struct ilo_render *r,
419                         const struct ilo_state_vector *ilo,
420                         struct ilo_render_draw_session *session);
421 
422 void
423 gen6_draw_common_sip(struct ilo_render *r,
424                      const struct ilo_state_vector *ilo,
425                      struct ilo_render_draw_session *session);
426 
427 void
428 gen6_draw_common_base_address(struct ilo_render *r,
429                               const struct ilo_state_vector *ilo,
430                               struct ilo_render_draw_session *session);
431 
432 void
433 gen6_draw_vf(struct ilo_render *r,
434              const struct ilo_state_vector *ilo,
435              struct ilo_render_draw_session *session);
436 
437 void
438 gen6_draw_vf_statistics(struct ilo_render *r,
439                         const struct ilo_state_vector *ilo,
440                         struct ilo_render_draw_session *session);
441 
442 void
443 gen6_draw_vs(struct ilo_render *r,
444              const struct ilo_state_vector *ilo,
445              struct ilo_render_draw_session *session);
446 
447 void
448 gen6_draw_clip(struct ilo_render *r,
449                const struct ilo_state_vector *ilo,
450                struct ilo_render_draw_session *session);
451 
452 void
453 gen6_draw_sf_rect(struct ilo_render *r,
454                   const struct ilo_state_vector *ilo,
455                   struct ilo_render_draw_session *session);
456 
457 void
458 gen6_draw_wm_raster(struct ilo_render *r,
459                     const struct ilo_state_vector *ilo,
460                     struct ilo_render_draw_session *session);
461 
462 void
463 gen7_draw_common_pcb_alloc(struct ilo_render *r,
464                            const struct ilo_state_vector *vec,
465                            struct ilo_render_draw_session *session);
466 
467 void
468 gen7_draw_common_pointers_1(struct ilo_render *r,
469                             const struct ilo_state_vector *vec,
470                             struct ilo_render_draw_session *session);
471 
472 void
473 gen7_draw_common_urb(struct ilo_render *r,
474                      const struct ilo_state_vector *vec,
475                      struct ilo_render_draw_session *session);
476 
477 void
478 gen7_draw_common_pointers_2(struct ilo_render *r,
479                             const struct ilo_state_vector *vec,
480                             struct ilo_render_draw_session *session);
481 
482 void
483 gen7_draw_vs(struct ilo_render *r,
484              const struct ilo_state_vector *vec,
485              struct ilo_render_draw_session *session);
486 
487 void
488 gen7_draw_ds(struct ilo_render *r,
489              const struct ilo_state_vector *vec,
490              struct ilo_render_draw_session *session);
491 
492 void
493 gen7_draw_te(struct ilo_render *r,
494              const struct ilo_state_vector *vec,
495              struct ilo_render_draw_session *session);
496 
497 void
498 gen7_draw_hs(struct ilo_render *r,
499              const struct ilo_state_vector *vec,
500              struct ilo_render_draw_session *session);
501 
502 void
503 gen7_draw_gs(struct ilo_render *r,
504              const struct ilo_state_vector *vec,
505              struct ilo_render_draw_session *session);
506 
507 void
508 gen7_draw_sol(struct ilo_render *r,
509               const struct ilo_state_vector *vec,
510               struct ilo_render_draw_session *session);
511 
512 #endif /* ILO_RENDER_GEN_H */
513