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