xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/llvmpipe/lp_setup.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /**
29  * Tiling engine.
30  *
31  * Builds per-tile display lists and executes them on calls to
32  * lp_setup_flush().
33  */
34 
35 #include <limits.h>
36 
37 #include "pipe/p_defines.h"
38 #include "util/u_framebuffer.h"
39 #include "util/u_inlines.h"
40 #include "util/u_memory.h"
41 #include "util/u_pack_color.h"
42 #include "util/u_cpu_detect.h"
43 #include "util/u_viewport.h"
44 #include "draw/draw_pipe.h"
45 #include "util/os_time.h"
46 #include "lp_context.h"
47 #include "lp_memory.h"
48 #include "lp_scene.h"
49 #include "lp_texture.h"
50 #include "lp_debug.h"
51 #include "lp_fence.h"
52 #include "lp_query.h"
53 #include "lp_rast.h"
54 #include "lp_setup_context.h"
55 #include "lp_screen.h"
56 #include "lp_state.h"
57 #include "lp_jit.h"
58 #include "frontend/sw_winsys.h"
59 
60 #include "draw/draw_context.h"
61 #include "draw/draw_vbuf.h"
62 
63 
64 static bool
65 try_update_scene_state(struct lp_setup_context *setup);
66 
67 
68 static unsigned
lp_setup_wait_empty_scene(struct lp_setup_context * setup)69 lp_setup_wait_empty_scene(struct lp_setup_context *setup)
70 {
71    /* just use the first scene if we run out */
72    if (setup->scenes[0]->fence) {
73       lp_fence_wait(setup->scenes[0]->fence);
74       lp_scene_end_rasterization(setup->scenes[0]);
75    }
76    return 0;
77 }
78 
79 
80 static void
lp_setup_get_empty_scene(struct lp_setup_context * setup)81 lp_setup_get_empty_scene(struct lp_setup_context *setup)
82 {
83    assert(setup->scene == NULL);
84    unsigned i;
85 
86    /* try and find a scene that isn't being used */
87    for (i = 0; i < setup->num_active_scenes; i++) {
88       if (setup->scenes[i]->fence) {
89          if (lp_fence_signalled(setup->scenes[i]->fence)) {
90             lp_scene_end_rasterization(setup->scenes[i]);
91             break;
92          }
93       } else {
94          break;
95       }
96    }
97 
98    if (setup->num_active_scenes + 1 > MAX_SCENES) {
99       i = lp_setup_wait_empty_scene(setup);
100    } else if (i == setup->num_active_scenes) {
101       /* allocate a new scene */
102       struct lp_scene *scene = lp_scene_create(setup);
103       if (!scene) {
104          /* block and reuse scenes */
105          i = lp_setup_wait_empty_scene(setup);
106       } else {
107          LP_DBG(DEBUG_SETUP, "allocated scene: %d\n", setup->num_active_scenes);
108          setup->scenes[setup->num_active_scenes] = scene;
109          i = setup->num_active_scenes;
110          setup->num_active_scenes++;
111       }
112    }
113 
114    setup->scene = setup->scenes[i];
115    setup->scene->permit_linear_rasterizer = setup->permit_linear_rasterizer;
116    lp_scene_begin_binning(setup->scene, &setup->fb);
117 }
118 
119 
120 static void
first_triangle(struct lp_setup_context * setup,const float (* v0)[4],const float (* v1)[4],const float (* v2)[4])121 first_triangle(struct lp_setup_context *setup,
122                const float (*v0)[4],
123                const float (*v1)[4],
124                const float (*v2)[4])
125 {
126    assert(setup->state == SETUP_ACTIVE);
127    lp_setup_choose_triangle(setup);
128    setup->triangle(setup, v0, v1, v2);
129 }
130 
131 
132 static bool
first_rectangle(struct lp_setup_context * setup,const float (* v0)[4],const float (* v1)[4],const float (* v2)[4],const float (* v3)[4],const float (* v4)[4],const float (* v5)[4])133 first_rectangle(struct lp_setup_context *setup,
134                 const float (*v0)[4],
135                 const float (*v1)[4],
136                 const float (*v2)[4],
137                 const float (*v3)[4],
138                 const float (*v4)[4],
139                 const float (*v5)[4])
140 {
141    assert(setup->state == SETUP_ACTIVE);
142    lp_setup_choose_rect(setup);
143    return setup->rect(setup, v0, v1, v2, v3, v4, v5);
144 }
145 
146 
147 static void
first_line(struct lp_setup_context * setup,const float (* v0)[4],const float (* v1)[4])148 first_line(struct lp_setup_context *setup,
149            const float (*v0)[4],
150            const float (*v1)[4])
151 {
152    assert(setup->state == SETUP_ACTIVE);
153    lp_setup_choose_line(setup);
154    setup->line(setup, v0, v1);
155 }
156 
157 
158 static void
first_point(struct lp_setup_context * setup,const float (* v0)[4])159 first_point(struct lp_setup_context *setup,
160             const float (*v0)[4])
161 {
162    assert(setup->state == SETUP_ACTIVE);
163    lp_setup_choose_point(setup);
164    setup->point(setup, v0);
165 }
166 
167 
168 void
lp_setup_reset(struct lp_setup_context * setup)169 lp_setup_reset(struct lp_setup_context *setup)
170 {
171    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
172 
173    /* Reset derived state */
174    for (unsigned i = 0; i < ARRAY_SIZE(setup->constants); ++i) {
175       setup->constants[i].stored_size = 0;
176       setup->constants[i].stored_data = NULL;
177    }
178 
179    setup->fs.stored = NULL;
180    setup->dirty = ~0;
181 
182    /* no current bin */
183    setup->scene = NULL;
184 
185    /* Reset some state:
186     */
187    memset(&setup->clear, 0, sizeof(setup->clear));
188 
189    /* Have an explicit "start-binning" call and get rid of this
190     * pointer twiddling?
191     */
192    setup->line = first_line;
193    setup->point = first_point;
194    setup->triangle = first_triangle;
195    setup->rect = first_rectangle;
196 }
197 
198 
199 /** Rasterize all scene's bins */
200 static void
lp_setup_rasterize_scene(struct lp_setup_context * setup)201 lp_setup_rasterize_scene(struct lp_setup_context *setup)
202 {
203    struct lp_scene *scene = setup->scene;
204    struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);
205 
206    scene->num_active_queries = setup->active_binned_queries;
207    memcpy(scene->active_queries, setup->active_queries,
208           scene->num_active_queries * sizeof(scene->active_queries[0]));
209 
210    lp_scene_end_binning(scene);
211 
212    mtx_lock(&screen->rast_mutex);
213    lp_rast_queue_scene(screen->rast, scene);
214    mtx_unlock(&screen->rast_mutex);
215 
216    lp_setup_reset(setup);
217 
218    LP_DBG(DEBUG_SETUP, "%s done \n", __func__);
219 }
220 
221 
222 static bool
begin_binning(struct lp_setup_context * setup)223 begin_binning(struct lp_setup_context *setup)
224 {
225    struct lp_scene *scene = setup->scene;
226 
227    assert(scene);
228    assert(scene->fence == NULL);
229 
230    /* Always create a fence:
231     */
232    scene->fence = lp_fence_create(MAX2(1, setup->num_threads));
233    if (!scene->fence)
234       return false;
235 
236    if (!try_update_scene_state(setup)) {
237       return false;
238    }
239 
240    bool need_zsload = false;
241    if (setup->fb.zsbuf &&
242        ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
243         util_format_is_depth_and_stencil(setup->fb.zsbuf->format)) {
244       need_zsload = true;
245    }
246 
247    LP_DBG(DEBUG_SETUP, "%s color clear bufs: %x depth: %s\n", __func__,
248           setup->clear.flags >> 2,
249           need_zsload ? "clear": "load");
250 
251    if (setup->clear.flags & PIPE_CLEAR_COLOR) {
252       for (unsigned cbuf = 0; cbuf < setup->fb.nr_cbufs; cbuf++) {
253          assert(PIPE_CLEAR_COLOR0 == 1 << 2);
254          if (setup->clear.flags & (1 << (2 + cbuf))) {
255             union lp_rast_cmd_arg clearrb_arg;
256             struct lp_rast_clear_rb *cc_scene =
257                (struct lp_rast_clear_rb *)
258                   lp_scene_alloc(scene, sizeof(struct lp_rast_clear_rb));
259 
260             if (!cc_scene) {
261                return false;
262             }
263 
264             cc_scene->cbuf = cbuf;
265             cc_scene->color_val = setup->clear.color_val[cbuf];
266             clearrb_arg.clear_rb = cc_scene;
267 
268             if (!lp_scene_bin_everywhere(scene,
269                                          LP_RAST_OP_CLEAR_COLOR,
270                                          clearrb_arg)) {
271                return false;
272             }
273          }
274       }
275    }
276 
277    if (setup->fb.zsbuf) {
278       if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
279          if (!lp_scene_bin_everywhere(scene,
280                                       LP_RAST_OP_CLEAR_ZSTENCIL,
281                                       lp_rast_arg_clearzs(
282                                          setup->clear.zsvalue,
283                                          setup->clear.zsmask))) {
284             return false;
285          }
286       }
287    }
288 
289    setup->clear.flags = 0;
290    setup->clear.zsmask = 0;
291    setup->clear.zsvalue = 0;
292 
293    scene->had_queries = !!setup->active_binned_queries;
294 
295    LP_DBG(DEBUG_SETUP, "%s done\n", __func__);
296    return true;
297 }
298 
299 
300 /* This basically bins and then flushes any outstanding full-screen
301  * clears.
302  *
303  * TODO: fast path for fullscreen clears and no triangles.
304  */
305 static bool
execute_clears(struct lp_setup_context * setup)306 execute_clears(struct lp_setup_context *setup)
307 {
308    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
309 
310    return begin_binning(setup);
311 }
312 
313 
314 static const char *states[] = {
315    "FLUSHED",
316    "CLEARED",
317    "ACTIVE "
318 };
319 
320 
321 static bool
set_scene_state(struct lp_setup_context * setup,enum setup_state new_state,const char * reason)322 set_scene_state(struct lp_setup_context *setup,
323                 enum setup_state new_state,
324                 const char *reason)
325 {
326    const unsigned old_state = setup->state;
327 
328    if (old_state == new_state)
329       return true;
330 
331    if (LP_DEBUG & DEBUG_SCENE) {
332       debug_printf("%s old %s new %s%s%s\n",
333                    __func__,
334                    states[old_state],
335                    states[new_state],
336                    (new_state == SETUP_FLUSHED) ? ": " : "",
337                    (new_state == SETUP_FLUSHED) ? reason : "");
338 
339       if (new_state == SETUP_FLUSHED && setup->scene)
340          lp_debug_draw_bins_by_cmd_length(setup->scene);
341    }
342 
343    /* wait for a free/empty scene
344     */
345    if (old_state == SETUP_FLUSHED)
346       lp_setup_get_empty_scene(setup);
347 
348    switch (new_state) {
349    case SETUP_CLEARED:
350       break;
351    case SETUP_ACTIVE:
352       if (!begin_binning(setup))
353          goto fail;
354       break;
355    case SETUP_FLUSHED:
356       if (old_state == SETUP_CLEARED)
357          if (!execute_clears(setup))
358             goto fail;
359       lp_setup_rasterize_scene(setup);
360       assert(setup->scene == NULL);
361       break;
362    default:
363       assert(0 && "invalid setup state mode");
364       goto fail;
365    }
366 
367    setup->state = new_state;
368    return true;
369 
370 fail:
371    if (setup->scene) {
372       lp_scene_end_rasterization(setup->scene);
373       setup->scene = NULL;
374    }
375 
376    setup->state = SETUP_FLUSHED;
377    lp_setup_reset(setup);
378    return false;
379 }
380 
381 
382 void
lp_setup_flush(struct lp_setup_context * setup,const char * reason)383 lp_setup_flush(struct lp_setup_context *setup,
384                const char *reason)
385 {
386    set_scene_state(setup, SETUP_FLUSHED, reason);
387 }
388 
389 
390 void
lp_setup_bind_framebuffer(struct lp_setup_context * setup,const struct pipe_framebuffer_state * fb)391 lp_setup_bind_framebuffer(struct lp_setup_context *setup,
392                           const struct pipe_framebuffer_state *fb)
393 {
394    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
395 
396    /* Flush any old scene.
397     */
398    set_scene_state(setup, SETUP_FLUSHED, __func__);
399 
400    /*
401     * Ensure the old scene is not reused.
402     */
403    assert(!setup->scene);
404 
405    /* Set new state.  This will be picked up later when we next need a
406     * scene.
407     */
408    util_copy_framebuffer_state(&setup->fb, fb);
409    setup->framebuffer.x0 = 0;
410    setup->framebuffer.y0 = 0;
411    setup->framebuffer.x1 = fb->width-1;
412    setup->framebuffer.y1 = fb->height-1;
413    setup->viewport_index_slot = -1;
414    setup->dirty |= LP_SETUP_NEW_SCISSOR;
415 }
416 
417 
418 /*
419  * Try to clear one color buffer of the attached fb, either by binning a clear
420  * command or queuing up the clear for later (when binning is started).
421  */
422 static bool
lp_setup_try_clear_color_buffer(struct lp_setup_context * setup,const union pipe_color_union * color,unsigned cbuf)423 lp_setup_try_clear_color_buffer(struct lp_setup_context *setup,
424                                 const union pipe_color_union *color,
425                                 unsigned cbuf)
426 {
427    union lp_rast_cmd_arg clearrb_arg;
428    union util_color uc;
429    const enum pipe_format format = setup->fb.cbufs[cbuf]->format;
430 
431    LP_DBG(DEBUG_SETUP, "%s state %d\n", __func__, setup->state);
432 
433    util_pack_color_union(format, &uc, color);
434 
435    if (setup->state == SETUP_ACTIVE) {
436       struct lp_scene *scene = setup->scene;
437 
438       /* Add the clear to existing scene.  In the unusual case where
439        * both color and depth-stencil are being cleared when there's
440        * already been some rendering, we could discard the currently
441        * binned scene and start again, but I don't see that as being
442        * a common usage.
443        */
444       struct lp_rast_clear_rb *cc_scene =
445          (struct lp_rast_clear_rb *)
446             lp_scene_alloc_aligned(scene, sizeof(struct lp_rast_clear_rb), 8);
447 
448       if (!cc_scene) {
449          return false;
450       }
451 
452       cc_scene->cbuf = cbuf;
453       cc_scene->color_val = uc;
454       clearrb_arg.clear_rb = cc_scene;
455 
456       if (!lp_scene_bin_everywhere(scene,
457                                    LP_RAST_OP_CLEAR_COLOR,
458                                    clearrb_arg)) {
459          return false;
460       }
461    } else {
462       /* Put ourselves into the 'pre-clear' state, specifically to try
463        * and accumulate multiple clears to color and depth_stencil
464        * buffers which the app or gallium frontend might issue
465        * separately.
466        */
467       set_scene_state(setup, SETUP_CLEARED, __func__);
468 
469       assert(PIPE_CLEAR_COLOR0 == (1 << 2));
470       setup->clear.flags |= 1 << (cbuf + 2);
471       setup->clear.color_val[cbuf] = uc;
472    }
473 
474    return true;
475 }
476 
477 
478 static bool
lp_setup_try_clear_zs(struct lp_setup_context * setup,double depth,unsigned stencil,unsigned flags)479 lp_setup_try_clear_zs(struct lp_setup_context *setup,
480                       double depth,
481                       unsigned stencil,
482                       unsigned flags)
483 {
484    LP_DBG(DEBUG_SETUP, "%s state %d\n", __func__, setup->state);
485 
486    enum pipe_format format = setup->fb.zsbuf->format;
487 
488    const uint32_t zmask32 = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0;
489    const uint8_t smask8 = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0;
490 
491    uint64_t zsvalue = util_pack64_z_stencil(format, depth, stencil);
492    uint64_t zsmask = util_pack64_mask_z_stencil(format, zmask32, smask8);
493 
494    zsvalue &= zsmask;
495 
496    if (format == PIPE_FORMAT_Z24X8_UNORM ||
497        format == PIPE_FORMAT_X8Z24_UNORM) {
498       /*
499        * Make full mask if there's "X" bits so we can do full
500        * clear (without rmw).
501        */
502       uint32_t zsmask_full = util_pack_mask_z_stencil(format, ~0, ~0);
503       zsmask |= ~zsmask_full;
504    }
505 
506    if (setup->state == SETUP_ACTIVE) {
507       struct lp_scene *scene = setup->scene;
508 
509       /* Add the clear to existing scene.  In the unusual case where
510        * both color and depth-stencil are being cleared when there's
511        * already been some rendering, we could discard the currently
512        * binned scene and start again, but I don't see that as being
513        * a common usage.
514        */
515       if (!lp_scene_bin_everywhere(scene,
516                                    LP_RAST_OP_CLEAR_ZSTENCIL,
517                                    lp_rast_arg_clearzs(zsvalue, zsmask)))
518          return false;
519    } else {
520       /* Put ourselves into the 'pre-clear' state, specifically to try
521        * and accumulate multiple clears to color and depth_stencil
522        * buffers which the app or gallium frontend might issue
523        * separately.
524        */
525       set_scene_state(setup, SETUP_CLEARED, __func__);
526 
527       setup->clear.flags |= flags;
528 
529       setup->clear.zsmask |= zsmask;
530       setup->clear.zsvalue =
531          (setup->clear.zsvalue & ~zsmask) | (zsvalue & zsmask);
532    }
533 
534    return true;
535 }
536 
537 
538 void
lp_setup_clear(struct lp_setup_context * setup,const union pipe_color_union * color,double depth,unsigned stencil,unsigned flags)539 lp_setup_clear(struct lp_setup_context *setup,
540                const union pipe_color_union *color,
541                double depth,
542                unsigned stencil,
543                unsigned flags)
544 {
545    /*
546     * Note any of these (max 9) clears could fail (but at most there should
547     * be just one failure!). This avoids doing the previous succeeded
548     * clears again (we still clear tiles twice if a clear command succeeded
549     * partially for one buffer).
550     */
551    if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
552       unsigned flagszs = flags & PIPE_CLEAR_DEPTHSTENCIL;
553       if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs)) {
554          set_scene_state(setup, SETUP_FLUSHED, __func__);
555 
556          if (!lp_setup_try_clear_zs(setup, depth, stencil, flagszs))
557             assert(0);
558       }
559    }
560 
561    if (flags & PIPE_CLEAR_COLOR) {
562       assert(PIPE_CLEAR_COLOR0 == (1 << 2));
563       for (unsigned i = 0; i < setup->fb.nr_cbufs; i++) {
564          if ((flags & (1 << (2 + i))) && setup->fb.cbufs[i]) {
565             if (!lp_setup_try_clear_color_buffer(setup, color, i)) {
566                set_scene_state(setup, SETUP_FLUSHED, __func__);
567 
568                if (!lp_setup_try_clear_color_buffer(setup, color, i))
569                   assert(0);
570             }
571          }
572       }
573    }
574 }
575 
576 
577 void
lp_setup_bind_rasterizer(struct lp_setup_context * setup,const struct pipe_rasterizer_state * rast)578 lp_setup_bind_rasterizer(struct lp_setup_context *setup,
579                          const struct pipe_rasterizer_state *rast)
580 {
581    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
582 
583    setup->ccw_is_frontface = rast->front_ccw;
584    setup->cullmode = rast->cull_face;
585    setup->triangle = first_triangle;
586    setup->rect = first_rectangle;
587    setup->multisample = rast->multisample;
588    setup->pixel_offset = rast->half_pixel_center ? 0.5f : 0.0f;
589    setup->bottom_edge_rule = rast->bottom_edge_rule;
590 
591    if (setup->scissor_test != rast->scissor) {
592       setup->dirty |= LP_SETUP_NEW_SCISSOR;
593       setup->scissor_test = rast->scissor;
594    }
595 
596    setup->flatshade_first = rast->flatshade_first;
597    setup->line_width = rast->line_width;
598    setup->rectangular_lines = rast->line_rectangular;
599 
600    setup->point_size = rast->point_size;
601    setup->sprite_coord_enable = rast->sprite_coord_enable;
602    setup->sprite_coord_origin = rast->sprite_coord_mode;
603    setup->point_line_tri_clip = rast->point_line_tri_clip;
604    setup->point_size_per_vertex = rast->point_size_per_vertex;
605    setup->legacy_points = !rast->point_quad_rasterization && !setup->multisample;
606 }
607 
608 
609 void
lp_setup_set_setup_variant(struct lp_setup_context * setup,const struct lp_setup_variant * variant)610 lp_setup_set_setup_variant(struct lp_setup_context *setup,
611                            const struct lp_setup_variant *variant)
612 {
613    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
614 
615    setup->setup.variant = variant;
616 }
617 
618 
619 void
lp_setup_set_fs_variant(struct lp_setup_context * setup,struct lp_fragment_shader_variant * variant)620 lp_setup_set_fs_variant(struct lp_setup_context *setup,
621                         struct lp_fragment_shader_variant *variant)
622 {
623    LP_DBG(DEBUG_SETUP, "%s %p\n", __func__, variant);
624 
625    setup->fs.current.variant = variant;
626    setup->dirty |= LP_SETUP_NEW_FS;
627 }
628 
629 
630 void
lp_setup_set_fs_constants(struct lp_setup_context * setup,unsigned num,struct pipe_constant_buffer * buffers)631 lp_setup_set_fs_constants(struct lp_setup_context *setup,
632                           unsigned num,
633                           struct pipe_constant_buffer *buffers)
634 {
635    LP_DBG(DEBUG_SETUP, "%s %p\n", __func__, (void *) buffers);
636 
637    assert(num <= ARRAY_SIZE(setup->constants));
638 
639    unsigned i;
640    for (i = 0; i < num; ++i) {
641       util_copy_constant_buffer(&setup->constants[i].current,
642                                 &buffers[i], false);
643    }
644    for (; i < ARRAY_SIZE(setup->constants); i++) {
645       util_copy_constant_buffer(&setup->constants[i].current, NULL, false);
646    }
647    setup->dirty |= LP_SETUP_NEW_CONSTANTS;
648 }
649 
650 
651 void
lp_setup_set_fs_ssbos(struct lp_setup_context * setup,unsigned num,struct pipe_shader_buffer * buffers,uint32_t ssbo_write_mask)652 lp_setup_set_fs_ssbos(struct lp_setup_context *setup,
653                       unsigned num,
654                       struct pipe_shader_buffer *buffers,
655                       uint32_t ssbo_write_mask)
656 {
657    LP_DBG(DEBUG_SETUP, "%s %p\n", __func__, (void *) buffers);
658 
659    assert(num <= ARRAY_SIZE(setup->ssbos));
660 
661    unsigned i;
662    for (i = 0; i < num; ++i) {
663       util_copy_shader_buffer(&setup->ssbos[i].current, &buffers[i]);
664    }
665    for (; i < ARRAY_SIZE(setup->ssbos); i++) {
666       util_copy_shader_buffer(&setup->ssbos[i].current, NULL);
667    }
668    setup->ssbo_write_mask = ssbo_write_mask;
669    setup->dirty |= LP_SETUP_NEW_SSBOS;
670 }
671 
672 
673 void
lp_setup_set_fs_images(struct lp_setup_context * setup,unsigned num,struct pipe_image_view * images)674 lp_setup_set_fs_images(struct lp_setup_context *setup,
675                        unsigned num,
676                        struct pipe_image_view *images)
677 {
678    unsigned i;
679 
680    LP_DBG(DEBUG_SETUP, "%s %p\n", __func__, (void *) images);
681 
682    assert(num <= ARRAY_SIZE(setup->images));
683 
684    for (i = 0; i < num; ++i) {
685       const struct pipe_image_view *image = &images[i];
686       util_copy_image_view(&setup->images[i].current, &images[i]);
687 
688       struct pipe_resource *res = image->resource;
689       struct lp_jit_image *jit_image = &setup->fs.current.jit_resources.images[i];
690 
691       if (!res)
692          continue;
693 
694       lp_jit_image_from_pipe(jit_image, image);
695    }
696    for (; i < ARRAY_SIZE(setup->images); i++) {
697       util_copy_image_view(&setup->images[i].current, NULL);
698    }
699    setup->dirty |= LP_SETUP_NEW_FS;
700 }
701 
702 
703 void
lp_setup_set_alpha_ref_value(struct lp_setup_context * setup,float alpha_ref_value)704 lp_setup_set_alpha_ref_value(struct lp_setup_context *setup,
705                              float alpha_ref_value)
706 {
707    LP_DBG(DEBUG_SETUP, "%s %f\n", __func__, alpha_ref_value);
708 
709    if (setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) {
710       setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value;
711       setup->dirty |= LP_SETUP_NEW_FS;
712    }
713 }
714 
715 
716 void
lp_setup_set_stencil_ref_values(struct lp_setup_context * setup,const uint8_t refs[2])717 lp_setup_set_stencil_ref_values(struct lp_setup_context *setup,
718                                 const uint8_t refs[2])
719 {
720    LP_DBG(DEBUG_SETUP, "%s %d %d\n", __func__, refs[0], refs[1]);
721 
722    if (setup->fs.current.jit_context.stencil_ref_front != refs[0] ||
723        setup->fs.current.jit_context.stencil_ref_back != refs[1]) {
724       setup->fs.current.jit_context.stencil_ref_front = refs[0];
725       setup->fs.current.jit_context.stencil_ref_back = refs[1];
726       setup->dirty |= LP_SETUP_NEW_FS;
727    }
728 }
729 
730 
731 void
lp_setup_set_blend_color(struct lp_setup_context * setup,const struct pipe_blend_color * blend_color)732 lp_setup_set_blend_color(struct lp_setup_context *setup,
733                          const struct pipe_blend_color *blend_color)
734 {
735    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
736 
737    assert(blend_color);
738 
739    if (memcmp(&setup->blend_color.current,
740               blend_color, sizeof *blend_color) != 0) {
741       memcpy(&setup->blend_color.current, blend_color, sizeof *blend_color);
742       setup->dirty |= LP_SETUP_NEW_BLEND_COLOR;
743    }
744 }
745 
746 
747 void
lp_setup_set_scissors(struct lp_setup_context * setup,const struct pipe_scissor_state * scissors)748 lp_setup_set_scissors(struct lp_setup_context *setup,
749                       const struct pipe_scissor_state *scissors)
750 {
751    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
752 
753    assert(scissors);
754 
755    for (unsigned i = 0; i < PIPE_MAX_VIEWPORTS; ++i) {
756       setup->scissors[i].x0 = scissors[i].minx;
757       setup->scissors[i].x1 = scissors[i].maxx-1;
758       setup->scissors[i].y0 = scissors[i].miny;
759       setup->scissors[i].y1 = scissors[i].maxy-1;
760    }
761    setup->dirty |= LP_SETUP_NEW_SCISSOR;
762 }
763 
764 
765 void
lp_setup_set_sample_mask(struct lp_setup_context * setup,uint32_t sample_mask)766 lp_setup_set_sample_mask(struct lp_setup_context *setup,
767                          uint32_t sample_mask)
768 {
769    if (setup->fs.current.jit_context.sample_mask != sample_mask) {
770       setup->fs.current.jit_context.sample_mask = sample_mask;
771       setup->dirty |= LP_SETUP_NEW_FS;
772    }
773 }
774 
775 
776 void
lp_setup_set_rasterizer_discard(struct lp_setup_context * setup,bool rasterizer_discard)777 lp_setup_set_rasterizer_discard(struct lp_setup_context *setup,
778                                 bool rasterizer_discard)
779 {
780    if (setup->rasterizer_discard != rasterizer_discard) {
781       setup->rasterizer_discard = rasterizer_discard;
782       setup->line = first_line;
783       setup->point = first_point;
784       setup->triangle = first_triangle;
785       setup->rect = first_rectangle;
786    }
787 }
788 
789 
790 void
lp_setup_set_vertex_info(struct lp_setup_context * setup,struct vertex_info * vertex_info)791 lp_setup_set_vertex_info(struct lp_setup_context *setup,
792                          struct vertex_info *vertex_info)
793 {
794    /* XXX: just silently holding onto the pointer:
795     */
796    setup->vertex_info = vertex_info;
797 }
798 
799 
800 void
lp_setup_set_linear_mode(struct lp_setup_context * setup,bool mode)801 lp_setup_set_linear_mode(struct lp_setup_context *setup,
802                          bool mode)
803 {
804    /* The linear rasterizer requires sse2 both at compile and runtime,
805     * in particular for the code in lp_rast_linear_fallback.c.  This
806     * is more than ten-year-old technology, so it's a reasonable
807     * baseline.
808     */
809 #if DETECT_ARCH_SSE
810    setup->permit_linear_rasterizer = (mode &&
811                                       util_get_cpu_caps()->has_sse2);
812 #else
813    setup->permit_linear_rasterizer = false;
814 #endif
815 }
816 
817 
818 /**
819  * Called during state validation when LP_NEW_VIEWPORT is set.
820  */
821 void
lp_setup_set_viewports(struct lp_setup_context * setup,unsigned num_viewports,const struct pipe_viewport_state * viewports)822 lp_setup_set_viewports(struct lp_setup_context *setup,
823                        unsigned num_viewports,
824                        const struct pipe_viewport_state *viewports)
825 {
826    struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
827 
828    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
829 
830    assert(num_viewports <= PIPE_MAX_VIEWPORTS);
831    assert(viewports);
832 
833    /*
834     * Linear rasterizer path for scissor/viewport intersection.
835     *
836     * Calculate "scissor" rect from the (first) viewport.
837     * Just like stored scissor rects need inclusive coords.
838     * For rounding, assume half pixel center (d3d9 should not end up
839     * with fractional viewports) - quite obviously for msaa we'd need
840     * fractional values here (and elsewhere for the point bounding box).
841     *
842     * See: lp_setup.c::try_update_scene_state
843     */
844    const float half_height = fabsf(viewports[0].scale[1]);
845    const float x0 = viewports[0].translate[0] - viewports[0].scale[0];
846    const float y0 = viewports[0].translate[1] - half_height;
847 
848    setup->vpwh.x0 = (int)(x0 + 0.499f);
849    setup->vpwh.x1 = (int)(viewports[0].scale[0] * 2.0f + x0 - 0.501f);
850    setup->vpwh.y0 = (int)(y0 + 0.499f);
851    setup->vpwh.y1 = (int)(half_height * 2.0f + y0 - 0.501f);
852    setup->dirty |= LP_SETUP_NEW_SCISSOR;
853 
854    /*
855     * For use in lp_state_fs.c, propagate the viewport values for all viewports.
856     */
857    for (unsigned i = 0; i < num_viewports; i++) {
858       float min_depth, max_depth;
859       util_viewport_zmin_zmax(&viewports[i], lp->rasterizer->clip_halfz,
860                               &min_depth, &max_depth);
861 
862       if (setup->viewports[i].min_depth != min_depth ||
863           setup->viewports[i].max_depth != max_depth) {
864           setup->viewports[i].min_depth = min_depth;
865           setup->viewports[i].max_depth = max_depth;
866           setup->dirty |= LP_SETUP_NEW_VIEWPORTS;
867       }
868    }
869 }
870 
871 
872 /**
873  * Called directly by llvmpipe_set_sampler_views
874  */
875 void
lp_setup_set_fragment_sampler_views(struct lp_setup_context * setup,unsigned num,struct pipe_sampler_view ** views)876 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
877                                     unsigned num,
878                                     struct pipe_sampler_view **views)
879 {
880    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
881 
882    assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
883 
884    const unsigned max_tex_num = MAX2(num, setup->fs.current_tex_num);
885 
886    for (unsigned i = 0; i < max_tex_num; i++) {
887       const struct pipe_sampler_view *view = i < num ? views[i] : NULL;
888 
889       /* We are going to overwrite/unref the current texture further below. If
890        * set, make sure to unmap its resource to avoid leaking previous
891        * mapping.  */
892       if (setup->fs.current_tex[i])
893          llvmpipe_resource_unmap(setup->fs.current_tex[i], 0, 0);
894 
895       if (view) {
896          struct pipe_resource *res = view->texture;
897          struct lp_jit_texture *jit_tex;
898          jit_tex = &setup->fs.current.jit_resources.textures[i];
899 
900          /* We're referencing the texture's internal data, so save a
901           * reference to it.
902           */
903          pipe_resource_reference(&setup->fs.current_tex[i], res);
904 
905          lp_jit_texture_from_pipe(jit_tex, view);
906       } else {
907          pipe_resource_reference(&setup->fs.current_tex[i], NULL);
908       }
909    }
910    setup->fs.current_tex_num = num;
911 
912    setup->dirty |= LP_SETUP_NEW_FS;
913 }
914 
915 
916 /**
917  * Called during state validation when LP_NEW_SAMPLER is set.
918  */
919 void
lp_setup_set_fragment_sampler_state(struct lp_setup_context * setup,unsigned num,struct pipe_sampler_state ** samplers)920 lp_setup_set_fragment_sampler_state(struct lp_setup_context *setup,
921                                     unsigned num,
922                                     struct pipe_sampler_state **samplers)
923 {
924    LP_DBG(DEBUG_SETUP, "%s\n", __func__);
925 
926    assert(num <= PIPE_MAX_SAMPLERS);
927 
928    for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++) {
929       const struct pipe_sampler_state *sampler = i < num ? samplers[i] : NULL;
930 
931       if (sampler) {
932          struct lp_jit_sampler *jit_sam;
933          jit_sam = &setup->fs.current.jit_resources.samplers[i];
934 
935          lp_jit_sampler_from_pipe(jit_sam, sampler);
936       }
937    }
938 
939    setup->dirty |= LP_SETUP_NEW_FS;
940 }
941 
942 
943 /**
944  * Is the given texture referenced by any scene?
945  * Note: we have to check all scenes including any scenes currently
946  * being rendered and the current scene being built.
947  */
948 unsigned
lp_setup_is_resource_referenced(const struct lp_setup_context * setup,const struct pipe_resource * texture)949 lp_setup_is_resource_referenced(const struct lp_setup_context *setup,
950                                 const struct pipe_resource *texture)
951 {
952    /* check the render targets */
953    for (unsigned i = 0; i < setup->fb.nr_cbufs; i++) {
954       if (setup->fb.cbufs[i] && setup->fb.cbufs[i]->texture == texture)
955          return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
956    }
957    if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) {
958       return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
959    }
960 
961    /* check resources referenced by active scenes */
962    for (unsigned i = 0; i < setup->num_active_scenes; i++) {
963       struct lp_scene *scene = setup->scenes[i];
964 
965       mtx_lock(&scene->mutex);
966       unsigned ref = lp_scene_is_resource_referenced(scene, texture);
967       mtx_unlock(&scene->mutex);
968       if (ref)
969          return ref;
970    }
971 
972    return LP_UNREFERENCED;
973 }
974 
975 
976 /**
977  * Called by vbuf code when we're about to draw something.
978  *
979  * This function stores all dirty state in the current scene's display list
980  * memory, via lp_scene_alloc().  We can not pass pointers of mutable state to
981  * the JIT functions, as the JIT functions will be called later on, most likely
982  * on a different thread.
983  *
984  * When processing dirty state it is imperative that we don't refer to any
985  * pointers previously allocated with lp_scene_alloc() in this function (or any
986  * function) as they may belong to a scene freed since then.
987  */
988 static bool
try_update_scene_state(struct lp_setup_context * setup)989 try_update_scene_state(struct lp_setup_context *setup)
990 {
991    bool new_scene = (setup->fs.stored == NULL);
992    struct lp_scene *scene = setup->scene;
993 
994    assert(scene);
995 
996    if (setup->dirty & LP_SETUP_NEW_VIEWPORTS) {
997       /*
998        * Record new depth range state for changes due to viewport updates.
999        *
1000        * TODO: Collapse the existing viewport and depth range information
1001        *       into one structure, for access by JIT.
1002        */
1003       struct lp_jit_viewport *stored;
1004 
1005       stored = (struct lp_jit_viewport *)
1006          lp_scene_alloc(scene, sizeof setup->viewports);
1007 
1008       if (!stored) {
1009          assert(!new_scene);
1010          return false;
1011       }
1012 
1013       memcpy(stored, setup->viewports, sizeof setup->viewports);
1014 
1015       setup->fs.current.jit_context.viewports = stored;
1016       setup->dirty |= LP_SETUP_NEW_FS;
1017    }
1018 
1019    if (setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
1020       /* Alloc u8_blend_color (16 x i8) and f_blend_color (4 or 8 x f32) */
1021       const unsigned size = 4 * 16 * sizeof(uint8_t)
1022                           + (LP_MAX_VECTOR_LENGTH / 4) * sizeof(float);
1023 
1024       uint8_t *stored =
1025          lp_scene_alloc_aligned(scene, size, LP_MIN_VECTOR_ALIGN);
1026 
1027       if (!stored) {
1028          assert(!new_scene);
1029          return false;
1030       }
1031 
1032       /* Store floating point colour (after ubyte colors (see below)) */
1033       float *fstored = (float *) (stored + 4 * 16);
1034       for (unsigned i = 0; i < (LP_MAX_VECTOR_LENGTH / 4); ++i) {
1035          fstored[i] = setup->blend_color.current.color[i % 4];
1036       }
1037 
1038       /* smear each blend color component across 16 ubyte elements */
1039       for (unsigned i = 0; i < 4; ++i) {
1040          uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
1041          for (unsigned j = 0; j < 16; ++j) {
1042             stored[i*16 + j] = c;
1043          }
1044       }
1045 
1046       setup->blend_color.stored = stored;
1047       setup->fs.current.jit_context.u8_blend_color = stored;
1048       setup->fs.current.jit_context.f_blend_color = fstored;
1049       setup->dirty |= LP_SETUP_NEW_FS;
1050    }
1051 
1052    struct llvmpipe_context *llvmpipe = llvmpipe_context(setup->pipe);
1053    if (llvmpipe->dirty & LP_NEW_FS_CONSTANTS)
1054       lp_setup_set_fs_constants(llvmpipe->setup,
1055                                 ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]),
1056                                 llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
1057 
1058    if (setup->dirty & LP_SETUP_NEW_CONSTANTS) {
1059       for (unsigned i = 0; i < ARRAY_SIZE(setup->constants); ++i) {
1060          lp_jit_buffer_from_pipe_const(&setup->fs.current.jit_resources.constants[i],
1061                                        &setup->constants[i].current, setup->pipe->screen);
1062          if (setup->constants[i].current.buffer &&
1063              !lp_scene_add_resource_reference(scene,
1064                            setup->constants[i].current.buffer,
1065                            new_scene, false)) {
1066             assert(!new_scene);
1067             return false;
1068          }
1069          setup->dirty |= LP_SETUP_NEW_FS;
1070       }
1071    }
1072 
1073    if (setup->dirty & LP_SETUP_NEW_SSBOS) {
1074       for (unsigned i = 0; i < ARRAY_SIZE(setup->ssbos); ++i) {
1075          lp_jit_buffer_from_pipe(&setup->fs.current.jit_resources.ssbos[i],
1076                                  &setup->ssbos[i].current);
1077          setup->dirty |= LP_SETUP_NEW_FS;
1078       }
1079    }
1080 
1081    if (setup->dirty & LP_SETUP_NEW_FS) {
1082       if (!setup->fs.stored ||
1083           memcmp(setup->fs.stored,
1084                  &setup->fs.current,
1085                  sizeof setup->fs.current) != 0) {
1086          /* The fs state that's been stored in the scene is different from
1087           * the new, current state.  So allocate a new lp_rast_state object
1088           * and append it to the bin's setup data buffer.
1089           */
1090          struct lp_rast_state *stored =
1091             (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
1092          if (!stored) {
1093             assert(!new_scene);
1094             return false;
1095          }
1096 
1097          memcpy(&stored->jit_context,
1098                 &setup->fs.current.jit_context,
1099                 sizeof setup->fs.current.jit_context);
1100          memcpy(&stored->jit_resources,
1101                 &setup->fs.current.jit_resources,
1102                 sizeof setup->fs.current.jit_resources);
1103 
1104          stored->jit_resources.aniso_filter_table =
1105             lp_build_sample_aniso_filter_table();
1106          stored->variant = setup->fs.current.variant;
1107 
1108          if (!lp_scene_add_frag_shader_reference(scene,
1109                                                  setup->fs.current.variant)) {
1110             return false;
1111          }
1112 
1113          setup->fs.stored = stored;
1114 
1115          /* The scene now references the textures in the rasterization
1116           * state record.  Note that now.
1117           */
1118          for (unsigned i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
1119             if (setup->fs.current_tex[i]) {
1120                if (!lp_scene_add_resource_reference(scene,
1121                                                     setup->fs.current_tex[i],
1122                                                     new_scene, false)) {
1123                   assert(!new_scene);
1124                   return false;
1125                }
1126             }
1127          }
1128 
1129          for (unsigned i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
1130             if (setup->ssbos[i].current.buffer) {
1131                if (!lp_scene_add_resource_reference(scene,
1132                                setup->ssbos[i].current.buffer,
1133                                new_scene, setup->ssbo_write_mask & (1 << i))) {
1134                   assert(!new_scene);
1135                   return false;
1136                }
1137             }
1138          }
1139 
1140          for (unsigned i = 0; i < ARRAY_SIZE(setup->images); i++) {
1141             if (setup->images[i].current.resource) {
1142                if (!lp_scene_add_resource_reference(scene,
1143                                                     setup->images[i].current.resource,
1144                                                     new_scene,
1145                                                     setup->images[i].current.shader_access & PIPE_IMAGE_ACCESS_WRITE)) {
1146                   assert(!new_scene);
1147                   return false;
1148                }
1149             }
1150          }
1151       }
1152    }
1153 
1154    if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
1155       for (unsigned i = 0; i < PIPE_MAX_VIEWPORTS; ++i) {
1156          setup->draw_regions[i] = setup->framebuffer;
1157          if (setup->scissor_test) {
1158             u_rect_possible_intersection(&setup->scissors[i],
1159                                          &setup->draw_regions[i]);
1160          }
1161       }
1162       if (setup->permit_linear_rasterizer) {
1163          /* NOTE: this only takes first vp into account. */
1164          bool need_vp_scissoring =
1165             !!memcmp(&setup->vpwh, &setup->framebuffer,
1166                      sizeof(setup->framebuffer));
1167 
1168          assert(setup->viewport_index_slot < 0);
1169          if (need_vp_scissoring) {
1170             u_rect_possible_intersection(&setup->vpwh,
1171                                          &setup->draw_regions[0]);
1172          }
1173       } else if (setup->point_line_tri_clip) {
1174          /*
1175           * for d3d-style point clipping, we're going to need
1176           * the fake vp scissor too. Hence do the intersection with vp,
1177           * but don't indicate this. As above this will only work for first vp
1178           * which should be ok because we instruct draw to only skip point
1179           * clipping when there's only one viewport (this works because d3d10
1180           * points are always single pixel).
1181           * (Also note that if we have permit_linear_rasterizer this will
1182           * cause large points to always get vp scissored, regardless the
1183           * point_line_tri_clip setting.)
1184           */
1185          bool need_vp_scissoring =
1186             !!memcmp(&setup->vpwh, &setup->framebuffer,
1187                      sizeof(setup->framebuffer));
1188          if (need_vp_scissoring) {
1189             u_rect_possible_intersection(&setup->vpwh,
1190                                          &setup->draw_regions[0]);
1191          }
1192       }
1193    }
1194 
1195    setup->dirty = 0;
1196 
1197    assert(setup->fs.stored);
1198    return true;
1199 }
1200 
1201 
1202 bool
lp_setup_update_state(struct lp_setup_context * setup,bool update_scene)1203 lp_setup_update_state(struct lp_setup_context *setup,
1204                       bool update_scene)
1205 {
1206    /* Some of the 'draw' pipeline stages may have changed some driver state.
1207     * Make sure we've processed those state changes before anything else.
1208     *
1209     * XXX this is the only place where llvmpipe_context is used in the
1210     * setup code.  This may get refactored/changed...
1211     */
1212    {
1213       struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
1214       if (lp->dirty) {
1215          llvmpipe_update_derived(lp);
1216       }
1217 
1218       if (lp->setup->dirty) {
1219          llvmpipe_update_setup(lp);
1220       }
1221 
1222       assert(setup->setup.variant);
1223 
1224       /* Will probably need to move this somewhere else, just need
1225        * to know about vertex shader point size attribute.
1226        */
1227       setup->psize_slot = lp->psize_slot;
1228       setup->viewport_index_slot = lp->viewport_index_slot;
1229       setup->layer_slot = lp->layer_slot;
1230       setup->face_slot = lp->face_slot;
1231 
1232       assert(lp->dirty == 0);
1233 
1234       assert(lp->setup_variant.key.size ==
1235              setup->setup.variant->key.size);
1236 
1237       assert(memcmp(&lp->setup_variant.key,
1238                     &setup->setup.variant->key,
1239                     setup->setup.variant->key.size) == 0);
1240    }
1241 
1242    if (update_scene && setup->state != SETUP_ACTIVE) {
1243       if (!set_scene_state(setup, SETUP_ACTIVE, __func__))
1244          return false;
1245    }
1246 
1247    /* Only call into update_scene_state() if we already have a
1248     * scene:
1249     */
1250    if (update_scene && setup->scene) {
1251       assert(setup->state == SETUP_ACTIVE);
1252 
1253       if (try_update_scene_state(setup))
1254          return true;
1255 
1256       /* Update failed, try to restart the scene.
1257        *
1258        * Cannot call lp_setup_flush_and_restart() directly here
1259        * because of potential recursion.
1260        */
1261       if (!set_scene_state(setup, SETUP_FLUSHED, __func__))
1262          return false;
1263 
1264       if (!set_scene_state(setup, SETUP_ACTIVE, __func__))
1265          return false;
1266 
1267       if (!setup->scene)
1268          return false;
1269 
1270       return try_update_scene_state(setup);
1271    }
1272 
1273    return true;
1274 }
1275 
1276 
1277 
1278 /* Only caller is lp_setup_vbuf_destroy()
1279  */
1280 void
lp_setup_destroy(struct lp_setup_context * setup)1281 lp_setup_destroy(struct lp_setup_context *setup)
1282 {
1283    lp_setup_reset(setup);
1284 
1285    util_unreference_framebuffer_state(&setup->fb);
1286 
1287    for (unsigned i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
1288       struct pipe_resource **res_ptr = &setup->fs.current_tex[i];
1289       if (*res_ptr)
1290          llvmpipe_resource_unmap(*res_ptr, 0, 0);
1291       pipe_resource_reference(res_ptr, NULL);
1292    }
1293 
1294    for (unsigned i = 0; i < ARRAY_SIZE(setup->constants); i++) {
1295       pipe_resource_reference(&setup->constants[i].current.buffer, NULL);
1296    }
1297 
1298    for (unsigned i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
1299       pipe_resource_reference(&setup->ssbos[i].current.buffer, NULL);
1300    }
1301 
1302    for (unsigned i = 0; i < ARRAY_SIZE(setup->images); i++) {
1303       pipe_resource_reference(&setup->images[i].current.resource, NULL);
1304    }
1305 
1306    /* free the scenes in the 'empty' queue */
1307    for (unsigned i = 0; i < setup->num_active_scenes; i++) {
1308       struct lp_scene *scene = setup->scenes[i];
1309 
1310       if (scene->fence)
1311          lp_fence_wait(scene->fence);
1312 
1313       lp_scene_destroy(scene);
1314    }
1315 
1316    LP_DBG(DEBUG_SETUP, "number of scenes used: %d\n", setup->num_active_scenes);
1317    slab_destroy(&setup->scene_slab);
1318 
1319    FREE(setup);
1320 }
1321 
1322 
1323 /**
1324  * Create a new primitive tiling engine.  Plug it into the backend of
1325  * the draw module.  Currently also creates a rasterizer to use with
1326  * it.
1327  */
1328 struct lp_setup_context *
lp_setup_create(struct pipe_context * pipe,struct draw_context * draw)1329 lp_setup_create(struct pipe_context *pipe,
1330                 struct draw_context *draw)
1331 {
1332    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
1333    struct lp_setup_context *setup = CALLOC_STRUCT(lp_setup_context);
1334    if (!setup) {
1335       goto no_setup;
1336    }
1337 
1338    lp_setup_init_vbuf(setup);
1339 
1340    setup->psize_slot = -1;
1341    setup->viewport_index_slot = -1;
1342    setup->layer_slot = -1;
1343    setup->face_slot = -1;
1344 
1345    /* Used only in update_state():
1346     */
1347    setup->pipe = pipe;
1348 
1349    setup->num_threads = screen->num_threads;
1350    setup->vbuf = draw_vbuf_stage(draw, &setup->base);
1351    if (!setup->vbuf) {
1352       goto no_vbuf;
1353    }
1354 
1355    draw_set_rasterize_stage(draw, setup->vbuf);
1356    draw_set_render(draw, &setup->base);
1357 
1358    slab_create(&setup->scene_slab,
1359                sizeof(struct lp_scene),
1360                INITIAL_SCENES);
1361    /* create just one scene for starting point */
1362    setup->scenes[0] = lp_scene_create(setup);
1363    if (!setup->scenes[0]) {
1364       goto no_scenes;
1365    }
1366    setup->num_active_scenes++;
1367 
1368    setup->triangle = first_triangle;
1369    setup->line     = first_line;
1370    setup->point    = first_point;
1371 
1372    setup->dirty = ~0;
1373 
1374    /* Initialize empty default fb correctly, so the rect is empty */
1375    setup->framebuffer.x1 = -1;
1376    setup->framebuffer.y1 = -1;
1377 
1378    return setup;
1379 
1380 no_scenes:
1381    for (unsigned i = 0; i < MAX_SCENES; i++) {
1382       if (setup->scenes[i]) {
1383          lp_scene_destroy(setup->scenes[i]);
1384       }
1385    }
1386 
1387    setup->vbuf->destroy(setup->vbuf);
1388 no_vbuf:
1389    FREE(setup);
1390 no_setup:
1391    return NULL;
1392 }
1393 
1394 
1395 /**
1396  * Put a BeginQuery command into all bins.
1397  */
1398 void
lp_setup_begin_query(struct lp_setup_context * setup,struct llvmpipe_query * pq)1399 lp_setup_begin_query(struct lp_setup_context *setup,
1400                      struct llvmpipe_query *pq)
1401 {
1402    set_scene_state(setup, SETUP_ACTIVE, "begin_query");
1403 
1404    if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1405          pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1406          pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1407          pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1408          pq->type == PIPE_QUERY_TIME_ELAPSED))
1409       return;
1410 
1411    /* init the query to its beginning state */
1412    assert(setup->active_binned_queries < LP_MAX_ACTIVE_BINNED_QUERIES);
1413    /* exceeding list size so just ignore the query */
1414    if (setup->active_binned_queries >= LP_MAX_ACTIVE_BINNED_QUERIES) {
1415       return;
1416    }
1417    assert(setup->active_queries[setup->active_binned_queries] == NULL);
1418    setup->active_queries[setup->active_binned_queries] = pq;
1419    setup->active_binned_queries++;
1420 
1421    assert(setup->scene);
1422    if (setup->scene) {
1423       if (!lp_scene_bin_everywhere(setup->scene,
1424                                    LP_RAST_OP_BEGIN_QUERY,
1425                                    lp_rast_arg_query(pq))) {
1426 
1427          if (!lp_setup_flush_and_restart(setup))
1428             return;
1429 
1430          if (!lp_scene_bin_everywhere(setup->scene,
1431                                       LP_RAST_OP_BEGIN_QUERY,
1432                                       lp_rast_arg_query(pq))) {
1433             return;
1434          }
1435       }
1436       setup->scene->had_queries |= true;
1437    }
1438 }
1439 
1440 
1441 /**
1442  * Put an EndQuery command into all bins.
1443  */
1444 void
lp_setup_end_query(struct lp_setup_context * setup,struct llvmpipe_query * pq)1445 lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
1446 {
1447    set_scene_state(setup, SETUP_ACTIVE, "end_query");
1448 
1449    assert(setup->scene);
1450    if (setup->scene) {
1451       /* pq->fence should be the fence of the *last* scene which
1452        * contributed to the query result.
1453        */
1454       lp_fence_reference(&pq->fence, setup->scene->fence);
1455 
1456       if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1457           pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1458           pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1459           pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1460           pq->type == PIPE_QUERY_TIMESTAMP ||
1461           pq->type == PIPE_QUERY_TIME_ELAPSED) {
1462          if (pq->type == PIPE_QUERY_TIMESTAMP &&
1463                !(setup->scene->tiles_x | setup->scene->tiles_y)) {
1464             /*
1465              * If there's a zero width/height framebuffer, there's no bins and
1466              * hence no rast task is ever run. So fill in something here instead.
1467              */
1468             pq->end[0] = os_time_get_nano();
1469          }
1470 
1471          if (!lp_scene_bin_everywhere(setup->scene,
1472                                       LP_RAST_OP_END_QUERY,
1473                                       lp_rast_arg_query(pq))) {
1474             if (!lp_setup_flush_and_restart(setup))
1475                goto fail;
1476 
1477             if (!lp_scene_bin_everywhere(setup->scene,
1478                                          LP_RAST_OP_END_QUERY,
1479                                          lp_rast_arg_query(pq))) {
1480                goto fail;
1481             }
1482          }
1483          setup->scene->had_queries |= true;
1484       }
1485    } else {
1486       struct llvmpipe_screen *screen = llvmpipe_screen(setup->pipe->screen);
1487       mtx_lock(&screen->rast_mutex);
1488       lp_rast_fence(screen->rast, &pq->fence);
1489       mtx_unlock(&screen->rast_mutex);
1490    }
1491 
1492 fail:
1493    /* Need to do this now not earlier since it still needs to be marked as
1494     * active when binning it would cause a flush.
1495     */
1496    if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1497       pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1498       pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1499       pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1500       pq->type == PIPE_QUERY_TIME_ELAPSED) {
1501       unsigned i;
1502 
1503       /* remove from active binned query list */
1504       for (i = 0; i < setup->active_binned_queries; i++) {
1505          if (setup->active_queries[i] == pq)
1506             break;
1507       }
1508       assert(i < setup->active_binned_queries);
1509       if (i == setup->active_binned_queries)
1510          return;
1511       setup->active_binned_queries--;
1512       setup->active_queries[i] = setup->active_queries[setup->active_binned_queries];
1513       setup->active_queries[setup->active_binned_queries] = NULL;
1514    }
1515 }
1516 
1517 
1518 bool
lp_setup_flush_and_restart(struct lp_setup_context * setup)1519 lp_setup_flush_and_restart(struct lp_setup_context *setup)
1520 {
1521    if (0) debug_printf("%s\n", __func__);
1522 
1523    assert(setup->state == SETUP_ACTIVE);
1524 
1525    if (!set_scene_state(setup, SETUP_FLUSHED, __func__))
1526       return false;
1527 
1528    if (!lp_setup_update_state(setup, true))
1529       return false;
1530 
1531    return true;
1532 }
1533 
1534 
1535 void
lp_setup_add_scissor_planes(const struct u_rect * scissor,struct lp_rast_plane * plane_s,bool s_planes[4],bool multisample)1536 lp_setup_add_scissor_planes(const struct u_rect *scissor,
1537                             struct lp_rast_plane *plane_s,
1538                             bool s_planes[4], bool multisample)
1539 {
1540    /*
1541     * When rasterizing scissored tris, use the intersection of the
1542     * triangle bounding box and the scissor rect to generate the
1543     * scissor planes.
1544     *
1545     * This permits us to cut off the triangle "tails" that are present
1546     * in the intermediate recursive levels caused when two of the
1547     * triangles edges don't diverge quickly enough to trivially reject
1548     * exterior blocks from the triangle.
1549     *
1550     * It's not really clear if it's worth worrying about these tails,
1551     * but since we generate the planes for each scissored tri, it's
1552     * free to trim them in this case.
1553     *
1554     * Note that otherwise, the scissor planes only vary in 'C' value,
1555     * and even then only on state-changes.  Could alternatively store
1556     * these planes elsewhere.
1557     * (Or only store the c value together with a bit indicating which
1558     * scissor edge this is, so rasterization would treat them differently
1559     * (easier to evaluate) to ordinary planes.)
1560     */
1561    int adj = multisample ? 127 : 0;
1562    if (s_planes[0]) {
1563       int x0 = scissor->x0 - 1;
1564       plane_s->dcdx = ~0U << 8;
1565       plane_s->dcdy = 0;
1566       plane_s->c = x0 << 8;
1567       plane_s->c += adj;
1568       plane_s->c = -plane_s->c; /* flip sign */
1569       plane_s->eo = 1 << 8;
1570       plane_s++;
1571    }
1572    if (s_planes[1]) {
1573       int x1 = scissor->x1;
1574       plane_s->dcdx = 1 << 8;
1575       plane_s->dcdy = 0;
1576       plane_s->c = x1 << 8;
1577       plane_s->c += 127 + adj;
1578       plane_s->eo = 0 << 8;
1579       plane_s++;
1580    }
1581    if (s_planes[2]) {
1582       int y0 = scissor->y0 - 1;
1583       plane_s->dcdx = 0;
1584       plane_s->dcdy = 1 << 8;
1585       plane_s->c = y0 << 8;
1586       plane_s->c += adj;
1587       plane_s->c = -plane_s->c; /* flip sign */
1588       plane_s->eo = 1 << 8;
1589       plane_s++;
1590    }
1591    if (s_planes[3]) {
1592       int y1 = scissor->y1;
1593       plane_s->dcdx = 0;
1594       plane_s->dcdy = ~0U << 8;
1595       plane_s->c = y1 << 8;
1596       plane_s->c += 127 + adj;
1597       plane_s->eo = 0;
1598       plane_s++;
1599    }
1600 }
1601