• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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->variant = setup->fs.current.variant;
1105 
1106          if (!lp_scene_add_frag_shader_reference(scene,
1107                                                  setup->fs.current.variant)) {
1108             return false;
1109          }
1110 
1111          setup->fs.stored = stored;
1112 
1113          /* The scene now references the textures in the rasterization
1114           * state record.  Note that now.
1115           */
1116          for (unsigned i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
1117             if (setup->fs.current_tex[i]) {
1118                if (!lp_scene_add_resource_reference(scene,
1119                                                     setup->fs.current_tex[i],
1120                                                     new_scene, false)) {
1121                   assert(!new_scene);
1122                   return false;
1123                }
1124             }
1125          }
1126 
1127          for (unsigned i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
1128             if (setup->ssbos[i].current.buffer) {
1129                if (!lp_scene_add_resource_reference(scene,
1130                                setup->ssbos[i].current.buffer,
1131                                new_scene, setup->ssbo_write_mask & (1 << i))) {
1132                   assert(!new_scene);
1133                   return false;
1134                }
1135             }
1136          }
1137 
1138          for (unsigned i = 0; i < ARRAY_SIZE(setup->images); i++) {
1139             if (setup->images[i].current.resource) {
1140                if (!lp_scene_add_resource_reference(scene,
1141                                                     setup->images[i].current.resource,
1142                                                     new_scene,
1143                                                     setup->images[i].current.shader_access & PIPE_IMAGE_ACCESS_WRITE)) {
1144                   assert(!new_scene);
1145                   return false;
1146                }
1147             }
1148          }
1149       }
1150    }
1151 
1152    if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
1153       for (unsigned i = 0; i < PIPE_MAX_VIEWPORTS; ++i) {
1154          setup->draw_regions[i] = setup->framebuffer;
1155          if (setup->scissor_test) {
1156             u_rect_possible_intersection(&setup->scissors[i],
1157                                          &setup->draw_regions[i]);
1158          }
1159       }
1160       if (setup->permit_linear_rasterizer) {
1161          /* NOTE: this only takes first vp into account. */
1162          bool need_vp_scissoring =
1163             !!memcmp(&setup->vpwh, &setup->framebuffer,
1164                      sizeof(setup->framebuffer));
1165 
1166          assert(setup->viewport_index_slot < 0);
1167          if (need_vp_scissoring) {
1168             u_rect_possible_intersection(&setup->vpwh,
1169                                          &setup->draw_regions[0]);
1170          }
1171       } else if (setup->point_line_tri_clip) {
1172          /*
1173           * for d3d-style point clipping, we're going to need
1174           * the fake vp scissor too. Hence do the intersection with vp,
1175           * but don't indicate this. As above this will only work for first vp
1176           * which should be ok because we instruct draw to only skip point
1177           * clipping when there's only one viewport (this works because d3d10
1178           * points are always single pixel).
1179           * (Also note that if we have permit_linear_rasterizer this will
1180           * cause large points to always get vp scissored, regardless the
1181           * point_line_tri_clip setting.)
1182           */
1183          bool need_vp_scissoring =
1184             !!memcmp(&setup->vpwh, &setup->framebuffer,
1185                      sizeof(setup->framebuffer));
1186          if (need_vp_scissoring) {
1187             u_rect_possible_intersection(&setup->vpwh,
1188                                          &setup->draw_regions[0]);
1189          }
1190       }
1191    }
1192 
1193    setup->dirty = 0;
1194 
1195    assert(setup->fs.stored);
1196    return true;
1197 }
1198 
1199 
1200 bool
lp_setup_update_state(struct lp_setup_context * setup,bool update_scene)1201 lp_setup_update_state(struct lp_setup_context *setup,
1202                       bool update_scene)
1203 {
1204    /* Some of the 'draw' pipeline stages may have changed some driver state.
1205     * Make sure we've processed those state changes before anything else.
1206     *
1207     * XXX this is the only place where llvmpipe_context is used in the
1208     * setup code.  This may get refactored/changed...
1209     */
1210    {
1211       struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
1212       if (lp->dirty) {
1213          llvmpipe_update_derived(lp);
1214       }
1215 
1216       if (lp->setup->dirty) {
1217          llvmpipe_update_setup(lp);
1218       }
1219 
1220       assert(setup->setup.variant);
1221 
1222       /* Will probably need to move this somewhere else, just need
1223        * to know about vertex shader point size attribute.
1224        */
1225       setup->psize_slot = lp->psize_slot;
1226       setup->viewport_index_slot = lp->viewport_index_slot;
1227       setup->layer_slot = lp->layer_slot;
1228       setup->face_slot = lp->face_slot;
1229 
1230       assert(lp->dirty == 0);
1231 
1232       assert(lp->setup_variant.key.size ==
1233              setup->setup.variant->key.size);
1234 
1235       assert(memcmp(&lp->setup_variant.key,
1236                     &setup->setup.variant->key,
1237                     setup->setup.variant->key.size) == 0);
1238    }
1239 
1240    if (update_scene && setup->state != SETUP_ACTIVE) {
1241       if (!set_scene_state(setup, SETUP_ACTIVE, __func__))
1242          return false;
1243    }
1244 
1245    /* Only call into update_scene_state() if we already have a
1246     * scene:
1247     */
1248    if (update_scene && setup->scene) {
1249       assert(setup->state == SETUP_ACTIVE);
1250 
1251       if (try_update_scene_state(setup))
1252          return true;
1253 
1254       /* Update failed, try to restart the scene.
1255        *
1256        * Cannot call lp_setup_flush_and_restart() directly here
1257        * because of potential recursion.
1258        */
1259       if (!set_scene_state(setup, SETUP_FLUSHED, __func__))
1260          return false;
1261 
1262       if (!set_scene_state(setup, SETUP_ACTIVE, __func__))
1263          return false;
1264 
1265       if (!setup->scene)
1266          return false;
1267 
1268       return try_update_scene_state(setup);
1269    }
1270 
1271    return true;
1272 }
1273 
1274 
1275 
1276 /* Only caller is lp_setup_vbuf_destroy()
1277  */
1278 void
lp_setup_destroy(struct lp_setup_context * setup)1279 lp_setup_destroy(struct lp_setup_context *setup)
1280 {
1281    lp_setup_reset(setup);
1282 
1283    util_unreference_framebuffer_state(&setup->fb);
1284 
1285    for (unsigned i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
1286       struct pipe_resource **res_ptr = &setup->fs.current_tex[i];
1287       if (*res_ptr)
1288          llvmpipe_resource_unmap(*res_ptr, 0, 0);
1289       pipe_resource_reference(res_ptr, NULL);
1290    }
1291 
1292    for (unsigned i = 0; i < ARRAY_SIZE(setup->constants); i++) {
1293       pipe_resource_reference(&setup->constants[i].current.buffer, NULL);
1294    }
1295 
1296    for (unsigned i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
1297       pipe_resource_reference(&setup->ssbos[i].current.buffer, NULL);
1298    }
1299 
1300    for (unsigned i = 0; i < ARRAY_SIZE(setup->images); i++) {
1301       pipe_resource_reference(&setup->images[i].current.resource, NULL);
1302    }
1303 
1304    /* free the scenes in the 'empty' queue */
1305    for (unsigned i = 0; i < setup->num_active_scenes; i++) {
1306       struct lp_scene *scene = setup->scenes[i];
1307 
1308       if (scene->fence)
1309          lp_fence_wait(scene->fence);
1310 
1311       lp_scene_destroy(scene);
1312    }
1313 
1314    LP_DBG(DEBUG_SETUP, "number of scenes used: %d\n", setup->num_active_scenes);
1315    slab_destroy(&setup->scene_slab);
1316 
1317    FREE(setup);
1318 }
1319 
1320 
1321 /**
1322  * Create a new primitive tiling engine.  Plug it into the backend of
1323  * the draw module.  Currently also creates a rasterizer to use with
1324  * it.
1325  */
1326 struct lp_setup_context *
lp_setup_create(struct pipe_context * pipe,struct draw_context * draw)1327 lp_setup_create(struct pipe_context *pipe,
1328                 struct draw_context *draw)
1329 {
1330    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
1331    struct lp_setup_context *setup = CALLOC_STRUCT(lp_setup_context);
1332    if (!setup) {
1333       goto no_setup;
1334    }
1335 
1336    lp_setup_init_vbuf(setup);
1337 
1338    setup->psize_slot = -1;
1339    setup->viewport_index_slot = -1;
1340    setup->layer_slot = -1;
1341    setup->face_slot = -1;
1342 
1343    /* Used only in update_state():
1344     */
1345    setup->pipe = pipe;
1346 
1347    setup->num_threads = screen->num_threads;
1348    setup->vbuf = draw_vbuf_stage(draw, &setup->base);
1349    if (!setup->vbuf) {
1350       goto no_vbuf;
1351    }
1352 
1353    draw_set_rasterize_stage(draw, setup->vbuf);
1354    draw_set_render(draw, &setup->base);
1355 
1356    slab_create(&setup->scene_slab,
1357                sizeof(struct lp_scene),
1358                INITIAL_SCENES);
1359    /* create just one scene for starting point */
1360    setup->scenes[0] = lp_scene_create(setup);
1361    if (!setup->scenes[0]) {
1362       goto no_scenes;
1363    }
1364    setup->num_active_scenes++;
1365 
1366    setup->triangle = first_triangle;
1367    setup->line     = first_line;
1368    setup->point    = first_point;
1369 
1370    setup->dirty = ~0;
1371 
1372    /* Initialize empty default fb correctly, so the rect is empty */
1373    setup->framebuffer.x1 = -1;
1374    setup->framebuffer.y1 = -1;
1375 
1376    return setup;
1377 
1378 no_scenes:
1379    for (unsigned i = 0; i < MAX_SCENES; i++) {
1380       if (setup->scenes[i]) {
1381          lp_scene_destroy(setup->scenes[i]);
1382       }
1383    }
1384 
1385    setup->vbuf->destroy(setup->vbuf);
1386 no_vbuf:
1387    FREE(setup);
1388 no_setup:
1389    return NULL;
1390 }
1391 
1392 
1393 /**
1394  * Put a BeginQuery command into all bins.
1395  */
1396 void
lp_setup_begin_query(struct lp_setup_context * setup,struct llvmpipe_query * pq)1397 lp_setup_begin_query(struct lp_setup_context *setup,
1398                      struct llvmpipe_query *pq)
1399 {
1400    set_scene_state(setup, SETUP_ACTIVE, "begin_query");
1401 
1402    if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1403          pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1404          pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1405          pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1406          pq->type == PIPE_QUERY_TIME_ELAPSED))
1407       return;
1408 
1409    /* init the query to its beginning state */
1410    assert(setup->active_binned_queries < LP_MAX_ACTIVE_BINNED_QUERIES);
1411    /* exceeding list size so just ignore the query */
1412    if (setup->active_binned_queries >= LP_MAX_ACTIVE_BINNED_QUERIES) {
1413       return;
1414    }
1415    assert(setup->active_queries[setup->active_binned_queries] == NULL);
1416    setup->active_queries[setup->active_binned_queries] = pq;
1417    setup->active_binned_queries++;
1418 
1419    assert(setup->scene);
1420    if (setup->scene) {
1421       if (!lp_scene_bin_everywhere(setup->scene,
1422                                    LP_RAST_OP_BEGIN_QUERY,
1423                                    lp_rast_arg_query(pq))) {
1424 
1425          if (!lp_setup_flush_and_restart(setup))
1426             return;
1427 
1428          if (!lp_scene_bin_everywhere(setup->scene,
1429                                       LP_RAST_OP_BEGIN_QUERY,
1430                                       lp_rast_arg_query(pq))) {
1431             return;
1432          }
1433       }
1434       setup->scene->had_queries |= true;
1435    }
1436 }
1437 
1438 
1439 /**
1440  * Put an EndQuery command into all bins.
1441  */
1442 void
lp_setup_end_query(struct lp_setup_context * setup,struct llvmpipe_query * pq)1443 lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
1444 {
1445    set_scene_state(setup, SETUP_ACTIVE, "end_query");
1446 
1447    assert(setup->scene);
1448    if (setup->scene) {
1449       /* pq->fence should be the fence of the *last* scene which
1450        * contributed to the query result.
1451        */
1452       lp_fence_reference(&pq->fence, setup->scene->fence);
1453 
1454       if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1455           pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1456           pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1457           pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1458           pq->type == PIPE_QUERY_TIMESTAMP ||
1459           pq->type == PIPE_QUERY_TIME_ELAPSED) {
1460          if (pq->type == PIPE_QUERY_TIMESTAMP &&
1461                !(setup->scene->tiles_x | setup->scene->tiles_y)) {
1462             /*
1463              * If there's a zero width/height framebuffer, there's no bins and
1464              * hence no rast task is ever run. So fill in something here instead.
1465              */
1466             pq->end[0] = os_time_get_nano();
1467          }
1468 
1469          if (!lp_scene_bin_everywhere(setup->scene,
1470                                       LP_RAST_OP_END_QUERY,
1471                                       lp_rast_arg_query(pq))) {
1472             if (!lp_setup_flush_and_restart(setup))
1473                goto fail;
1474 
1475             if (!lp_scene_bin_everywhere(setup->scene,
1476                                          LP_RAST_OP_END_QUERY,
1477                                          lp_rast_arg_query(pq))) {
1478                goto fail;
1479             }
1480          }
1481          setup->scene->had_queries |= true;
1482       }
1483    } else {
1484       struct llvmpipe_screen *screen = llvmpipe_screen(setup->pipe->screen);
1485       mtx_lock(&screen->rast_mutex);
1486       lp_rast_fence(screen->rast, &pq->fence);
1487       mtx_unlock(&screen->rast_mutex);
1488    }
1489 
1490 fail:
1491    /* Need to do this now not earlier since it still needs to be marked as
1492     * active when binning it would cause a flush.
1493     */
1494    if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER ||
1495       pq->type == PIPE_QUERY_OCCLUSION_PREDICATE ||
1496       pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE ||
1497       pq->type == PIPE_QUERY_PIPELINE_STATISTICS ||
1498       pq->type == PIPE_QUERY_TIME_ELAPSED) {
1499       unsigned i;
1500 
1501       /* remove from active binned query list */
1502       for (i = 0; i < setup->active_binned_queries; i++) {
1503          if (setup->active_queries[i] == pq)
1504             break;
1505       }
1506       assert(i < setup->active_binned_queries);
1507       if (i == setup->active_binned_queries)
1508          return;
1509       setup->active_binned_queries--;
1510       setup->active_queries[i] = setup->active_queries[setup->active_binned_queries];
1511       setup->active_queries[setup->active_binned_queries] = NULL;
1512    }
1513 }
1514 
1515 
1516 bool
lp_setup_flush_and_restart(struct lp_setup_context * setup)1517 lp_setup_flush_and_restart(struct lp_setup_context *setup)
1518 {
1519    if (0) debug_printf("%s\n", __func__);
1520 
1521    assert(setup->state == SETUP_ACTIVE);
1522 
1523    if (!set_scene_state(setup, SETUP_FLUSHED, __func__))
1524       return false;
1525 
1526    if (!lp_setup_update_state(setup, true))
1527       return false;
1528 
1529    return true;
1530 }
1531 
1532 
1533 void
lp_setup_add_scissor_planes(const struct u_rect * scissor,struct lp_rast_plane * plane_s,bool s_planes[4],bool multisample)1534 lp_setup_add_scissor_planes(const struct u_rect *scissor,
1535                             struct lp_rast_plane *plane_s,
1536                             bool s_planes[4], bool multisample)
1537 {
1538    /*
1539     * When rasterizing scissored tris, use the intersection of the
1540     * triangle bounding box and the scissor rect to generate the
1541     * scissor planes.
1542     *
1543     * This permits us to cut off the triangle "tails" that are present
1544     * in the intermediate recursive levels caused when two of the
1545     * triangles edges don't diverge quickly enough to trivially reject
1546     * exterior blocks from the triangle.
1547     *
1548     * It's not really clear if it's worth worrying about these tails,
1549     * but since we generate the planes for each scissored tri, it's
1550     * free to trim them in this case.
1551     *
1552     * Note that otherwise, the scissor planes only vary in 'C' value,
1553     * and even then only on state-changes.  Could alternatively store
1554     * these planes elsewhere.
1555     * (Or only store the c value together with a bit indicating which
1556     * scissor edge this is, so rasterization would treat them differently
1557     * (easier to evaluate) to ordinary planes.)
1558     */
1559    int adj = multisample ? 127 : 0;
1560    if (s_planes[0]) {
1561       int x0 = scissor->x0 - 1;
1562       plane_s->dcdx = ~0U << 8;
1563       plane_s->dcdy = 0;
1564       plane_s->c = x0 << 8;
1565       plane_s->c += adj;
1566       plane_s->c = -plane_s->c; /* flip sign */
1567       plane_s->eo = 1 << 8;
1568       plane_s++;
1569    }
1570    if (s_planes[1]) {
1571       int x1 = scissor->x1;
1572       plane_s->dcdx = 1 << 8;
1573       plane_s->dcdy = 0;
1574       plane_s->c = x1 << 8;
1575       plane_s->c += 127 + adj;
1576       plane_s->eo = 0 << 8;
1577       plane_s++;
1578    }
1579    if (s_planes[2]) {
1580       int y0 = scissor->y0 - 1;
1581       plane_s->dcdx = 0;
1582       plane_s->dcdy = 1 << 8;
1583       plane_s->c = y0 << 8;
1584       plane_s->c += adj;
1585       plane_s->c = -plane_s->c; /* flip sign */
1586       plane_s->eo = 1 << 8;
1587       plane_s++;
1588    }
1589    if (s_planes[3]) {
1590       int y1 = scissor->y1;
1591       plane_s->dcdx = 0;
1592       plane_s->dcdy = ~0U << 8;
1593       plane_s->c = y1 << 8;
1594       plane_s->c += 127 + adj;
1595       plane_s->eo = 0;
1596       plane_s++;
1597    }
1598 }
1599