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