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 64static boolean set_scene_state(struct lp_setup_context *, enum setup_state, 65 const char *reason); 66static boolean try_update_scene_state(struct lp_setup_context *setup); 67 68 69static unsigned 70lp_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 83static void 84lp_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 123static void 124first_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 135static boolean 136first_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 150static void 151first_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 161static void 162first_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 171void 172lp_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 */ 203static void 204lp_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 225static boolean 226begin_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 */ 308static boolean 309execute_clears(struct lp_setup_context *setup) 310{ 311 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); 312 313 return begin_binning(setup); 314} 315 316 317static const char *states[] = { 318 "FLUSHED", 319 "CLEARED", 320 "ACTIVE " 321}; 322 323 324static boolean 325set_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 377fail: 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 389void 390lp_setup_flush(struct lp_setup_context *setup, 391 const char *reason) 392{ 393 set_scene_state(setup, SETUP_FLUSHED, reason); 394} 395 396 397void 398lp_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 */ 428static boolean 429lp_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 485static boolean 486lp_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 546void 547lp_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 585void 586lp_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 617void 618lp_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 627void 628lp_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 638void 639lp_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 659void 660lp_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 681void 682lp_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 761void 762lp_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 774void 775lp_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 789void 790lp_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 805void 806lp_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 823void 824lp_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 834void 835lp_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 848void 849lp_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 858void 859lp_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 */ 879void 880lp_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 */ 933void 934lp_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 */ 1088void 1089lp_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 */ 1121unsigned 1122lp_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 */ 1168static boolean 1169try_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 1440boolean 1441lp_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 */ 1518void 1519lp_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 */ 1562struct lp_setup_context * 1563lp_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 1609no_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); 1617no_vbuf: 1618 FREE(setup); 1619no_setup: 1620 return NULL; 1621} 1622 1623 1624/** 1625 * Put a BeginQuery command into all bins. 1626 */ 1627void 1628lp_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 */ 1673void 1674lp_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 1722fail: 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 1748boolean 1749lp_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 1765void 1766lp_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