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