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