ilo_state.c revision a3ed98f7aa85636579a5696bf036ec13e5c9104a
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2012-2013 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv@lunarg.com> 26 */ 27 28#include "util/u_framebuffer.h" 29#include "util/u_helpers.h" 30#include "util/u_upload_mgr.h" 31 32#include "ilo_context.h" 33#include "ilo_resource.h" 34#include "ilo_shader.h" 35#include "ilo_state.h" 36 37static void 38finalize_shader_states(struct ilo_context *ilo) 39{ 40 unsigned type; 41 42 for (type = 0; type < PIPE_SHADER_TYPES; type++) { 43 struct ilo_shader_state *shader; 44 uint32_t state; 45 46 switch (type) { 47 case PIPE_SHADER_VERTEX: 48 shader = ilo->vs; 49 state = ILO_DIRTY_VS; 50 break; 51 case PIPE_SHADER_GEOMETRY: 52 shader = ilo->gs; 53 state = ILO_DIRTY_GS; 54 break; 55 case PIPE_SHADER_FRAGMENT: 56 shader = ilo->fs; 57 state = ILO_DIRTY_FS; 58 break; 59 default: 60 shader = NULL; 61 state = 0; 62 break; 63 } 64 65 if (!shader) 66 continue; 67 68 /* compile if the shader or the states it depends on changed */ 69 if (ilo->dirty & state) { 70 ilo_shader_select_kernel(shader, ilo, ILO_DIRTY_ALL); 71 } 72 else if (ilo_shader_select_kernel(shader, ilo, ilo->dirty)) { 73 /* mark the state dirty if a new kernel is selected */ 74 ilo->dirty |= state; 75 } 76 77 /* need to setup SBE for FS */ 78 if (type == PIPE_SHADER_FRAGMENT && ilo->dirty & 79 (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) { 80 if (ilo_shader_select_kernel_routing(shader, 81 (ilo->gs) ? ilo->gs : ilo->vs, ilo->rasterizer)) 82 ilo->dirty |= state; 83 } 84 } 85} 86 87static void 88finalize_cbuf_state(struct ilo_context *ilo, 89 struct ilo_cbuf_state *cbuf, 90 const struct ilo_shader_state *sh) 91{ 92 uint32_t upload_mask = cbuf->enabled_mask; 93 94 /* skip CBUF0 if the kernel does not need it */ 95 upload_mask &= 96 ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD); 97 98 while (upload_mask) { 99 const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 100 unsigned offset, i; 101 102 i = u_bit_scan(&upload_mask); 103 /* no need to upload */ 104 if (cbuf->cso[i].resource) 105 continue; 106 107 u_upload_data(ilo->uploader, 0, cbuf->cso[i].user_buffer_size, 108 cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource); 109 110 ilo_gpe_init_view_surface_for_buffer(ilo->dev, 111 ilo_buffer(cbuf->cso[i].resource), 112 offset, cbuf->cso[i].user_buffer_size, 113 util_format_get_blocksize(elem_format), elem_format, 114 false, false, &cbuf->cso[i].surface); 115 116 ilo->dirty |= ILO_DIRTY_CBUF; 117 } 118} 119 120static void 121finalize_constant_buffers(struct ilo_context *ilo) 122{ 123 if (ilo->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_VS)) 124 finalize_cbuf_state(ilo, &ilo->cbuf[PIPE_SHADER_VERTEX], ilo->vs); 125 126 if (ilo->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_FS)) 127 finalize_cbuf_state(ilo, &ilo->cbuf[PIPE_SHADER_FRAGMENT], ilo->fs); 128} 129 130static void 131finalize_index_buffer(struct ilo_context *ilo) 132{ 133 const bool need_upload = (ilo->draw->indexed && 134 (ilo->ib.user_buffer || ilo->ib.offset % ilo->ib.index_size)); 135 struct pipe_resource *current_hw_res = NULL; 136 137 if (!(ilo->dirty & ILO_DIRTY_IB) && !need_upload) 138 return; 139 140 pipe_resource_reference(¤t_hw_res, ilo->ib.hw_resource); 141 142 if (need_upload) { 143 const unsigned offset = ilo->ib.index_size * ilo->draw->start; 144 const unsigned size = ilo->ib.index_size * ilo->draw->count; 145 unsigned hw_offset; 146 147 if (ilo->ib.user_buffer) { 148 u_upload_data(ilo->uploader, 0, size, 149 ilo->ib.user_buffer + offset, &hw_offset, &ilo->ib.hw_resource); 150 } 151 else { 152 u_upload_buffer(ilo->uploader, 0, ilo->ib.offset + offset, size, 153 ilo->ib.buffer, &hw_offset, &ilo->ib.hw_resource); 154 } 155 156 /* the HW offset should be aligned */ 157 assert(hw_offset % ilo->ib.index_size == 0); 158 ilo->ib.draw_start_offset = hw_offset / ilo->ib.index_size; 159 160 /* 161 * INDEX[ilo->draw->start] in the original buffer is INDEX[0] in the HW 162 * resource 163 */ 164 ilo->ib.draw_start_offset -= ilo->draw->start; 165 } 166 else { 167 pipe_resource_reference(&ilo->ib.hw_resource, ilo->ib.buffer); 168 169 /* note that index size may be zero when the draw is not indexed */ 170 if (ilo->draw->indexed) 171 ilo->ib.draw_start_offset = ilo->ib.offset / ilo->ib.index_size; 172 else 173 ilo->ib.draw_start_offset = 0; 174 } 175 176 /* treat the IB as clean if the HW states do not change */ 177 if (ilo->ib.hw_resource == current_hw_res && 178 ilo->ib.hw_index_size == ilo->ib.index_size) 179 ilo->dirty &= ~ILO_DIRTY_IB; 180 else 181 ilo->ib.hw_index_size = ilo->ib.index_size; 182 183 pipe_resource_reference(¤t_hw_res, NULL); 184} 185 186/** 187 * Finalize states. Some states depend on other states and are 188 * incomplete/invalid until finalized. 189 */ 190void 191ilo_finalize_3d_states(struct ilo_context *ilo, 192 const struct pipe_draw_info *draw) 193{ 194 ilo->draw = draw; 195 196 finalize_shader_states(ilo); 197 finalize_constant_buffers(ilo); 198 finalize_index_buffer(ilo); 199 200 u_upload_unmap(ilo->uploader); 201} 202 203static void * 204ilo_create_blend_state(struct pipe_context *pipe, 205 const struct pipe_blend_state *state) 206{ 207 struct ilo_context *ilo = ilo_context(pipe); 208 struct ilo_blend_state *blend; 209 210 blend = MALLOC_STRUCT(ilo_blend_state); 211 assert(blend); 212 213 ilo_gpe_init_blend(ilo->dev, state, blend); 214 215 return blend; 216} 217 218static void 219ilo_bind_blend_state(struct pipe_context *pipe, void *state) 220{ 221 struct ilo_context *ilo = ilo_context(pipe); 222 223 ilo->blend = state; 224 225 ilo->dirty |= ILO_DIRTY_BLEND; 226} 227 228static void 229ilo_delete_blend_state(struct pipe_context *pipe, void *state) 230{ 231 FREE(state); 232} 233 234static void * 235ilo_create_sampler_state(struct pipe_context *pipe, 236 const struct pipe_sampler_state *state) 237{ 238 struct ilo_context *ilo = ilo_context(pipe); 239 struct ilo_sampler_cso *sampler; 240 241 sampler = MALLOC_STRUCT(ilo_sampler_cso); 242 assert(sampler); 243 244 ilo_gpe_init_sampler_cso(ilo->dev, state, sampler); 245 246 return sampler; 247} 248 249static void 250ilo_bind_sampler_states(struct pipe_context *pipe, unsigned shader, 251 unsigned start, unsigned count, void **samplers) 252{ 253 struct ilo_context *ilo = ilo_context(pipe); 254 struct ilo_sampler_state *dst = &ilo->sampler[shader]; 255 bool changed = false; 256 unsigned i; 257 258 assert(start + count <= Elements(dst->cso)); 259 260 if (samplers) { 261 for (i = 0; i < count; i++) { 262 if (dst->cso[start + i] != samplers[i]) { 263 dst->cso[start + i] = samplers[i]; 264 265 /* 266 * This function is sometimes called to reduce the number of bound 267 * samplers. Do not consider that as a state change (and create a 268 * new array of SAMPLER_STATE). 269 */ 270 if (samplers[i]) 271 changed = true; 272 } 273 } 274 } 275 else { 276 for (i = 0; i < count; i++) 277 dst->cso[start + i] = NULL; 278 } 279 280 if (dst->count <= start + count) { 281 if (samplers) 282 count += start; 283 else 284 count = start; 285 286 while (count > 0 && !dst->cso[count - 1]) 287 count--; 288 289 dst->count = count; 290 } 291 292 if (changed) { 293 switch (shader) { 294 case PIPE_SHADER_VERTEX: 295 ilo->dirty |= ILO_DIRTY_SAMPLER_VS; 296 break; 297 case PIPE_SHADER_GEOMETRY: 298 ilo->dirty |= ILO_DIRTY_SAMPLER_GS; 299 break; 300 case PIPE_SHADER_FRAGMENT: 301 ilo->dirty |= ILO_DIRTY_SAMPLER_FS; 302 break; 303 case PIPE_SHADER_COMPUTE: 304 ilo->dirty |= ILO_DIRTY_SAMPLER_CS; 305 break; 306 } 307 } 308} 309 310static void 311ilo_bind_fragment_sampler_states(struct pipe_context *pipe, 312 unsigned num_samplers, 313 void **samplers) 314{ 315 struct ilo_context *ilo = ilo_context(pipe); 316 317 ilo_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 318 0, num_samplers, samplers); 319 320 if (ilo->sampler[PIPE_SHADER_FRAGMENT].count > num_samplers) { 321 ilo_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, num_samplers, 322 ilo->sampler[PIPE_SHADER_FRAGMENT].count - num_samplers, NULL); 323 } 324} 325 326static void 327ilo_bind_vertex_sampler_states(struct pipe_context *pipe, 328 unsigned num_samplers, 329 void **samplers) 330{ 331 struct ilo_context *ilo = ilo_context(pipe); 332 333 ilo_bind_sampler_states(pipe, PIPE_SHADER_VERTEX, 334 0, num_samplers, samplers); 335 336 if (ilo->sampler[PIPE_SHADER_VERTEX].count > num_samplers) { 337 ilo_bind_sampler_states(pipe, PIPE_SHADER_VERTEX, num_samplers, 338 ilo->sampler[PIPE_SHADER_VERTEX].count - num_samplers, NULL); 339 } 340} 341 342static void 343ilo_bind_geometry_sampler_states(struct pipe_context *pipe, 344 unsigned num_samplers, 345 void **samplers) 346{ 347 struct ilo_context *ilo = ilo_context(pipe); 348 349 ilo_bind_sampler_states(pipe, PIPE_SHADER_GEOMETRY, 350 0, num_samplers, samplers); 351 352 if (ilo->sampler[PIPE_SHADER_GEOMETRY].count > num_samplers) { 353 ilo_bind_sampler_states(pipe, PIPE_SHADER_GEOMETRY, num_samplers, 354 ilo->sampler[PIPE_SHADER_GEOMETRY].count - num_samplers, NULL); 355 } 356} 357 358static void 359ilo_bind_compute_sampler_states(struct pipe_context *pipe, 360 unsigned start_slot, 361 unsigned num_samplers, 362 void **samplers) 363{ 364 ilo_bind_sampler_states(pipe, PIPE_SHADER_COMPUTE, 365 start_slot, num_samplers, samplers); 366} 367 368static void 369ilo_bind_sampler_states2(struct pipe_context *pipe, unsigned shader, 370 unsigned start, unsigned count, void **samplers) 371{ 372 switch (shader) { 373 case PIPE_SHADER_VERTEX: 374 ilo_bind_vertex_sampler_states(pipe, count, samplers); 375 break; 376 case PIPE_SHADER_GEOMETRY: 377 ilo_bind_geometry_sampler_states(pipe, count, samplers); 378 break; 379 case PIPE_SHADER_FRAGMENT: 380 ilo_bind_fragment_sampler_states(pipe, count, samplers); 381 break; 382 case PIPE_SHADER_COMPUTE: 383 ilo_bind_compute_sampler_states(pipe, start, count, samplers); 384 break; 385 } 386} 387 388static void 389ilo_delete_sampler_state(struct pipe_context *pipe, void *state) 390{ 391 FREE(state); 392} 393 394static void * 395ilo_create_rasterizer_state(struct pipe_context *pipe, 396 const struct pipe_rasterizer_state *state) 397{ 398 struct ilo_context *ilo = ilo_context(pipe); 399 struct ilo_rasterizer_state *rast; 400 401 rast = MALLOC_STRUCT(ilo_rasterizer_state); 402 assert(rast); 403 404 rast->state = *state; 405 ilo_gpe_init_rasterizer(ilo->dev, state, rast); 406 407 return rast; 408} 409 410static void 411ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state) 412{ 413 struct ilo_context *ilo = ilo_context(pipe); 414 415 ilo->rasterizer = state; 416 417 ilo->dirty |= ILO_DIRTY_RASTERIZER; 418} 419 420static void 421ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state) 422{ 423 FREE(state); 424} 425 426static void * 427ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe, 428 const struct pipe_depth_stencil_alpha_state *state) 429{ 430 struct ilo_context *ilo = ilo_context(pipe); 431 struct ilo_dsa_state *dsa; 432 433 dsa = MALLOC_STRUCT(ilo_dsa_state); 434 assert(dsa); 435 436 ilo_gpe_init_dsa(ilo->dev, state, dsa); 437 438 return dsa; 439} 440 441static void 442ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 443{ 444 struct ilo_context *ilo = ilo_context(pipe); 445 446 ilo->dsa = state; 447 448 ilo->dirty |= ILO_DIRTY_DSA; 449} 450 451static void 452ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 453{ 454 FREE(state); 455} 456 457static void * 458ilo_create_fs_state(struct pipe_context *pipe, 459 const struct pipe_shader_state *state) 460{ 461 struct ilo_context *ilo = ilo_context(pipe); 462 struct ilo_shader_state *shader; 463 464 shader = ilo_shader_create_fs(ilo->dev, state, ilo); 465 assert(shader); 466 467 ilo_shader_cache_add(ilo->shader_cache, shader); 468 469 return shader; 470} 471 472static void 473ilo_bind_fs_state(struct pipe_context *pipe, void *state) 474{ 475 struct ilo_context *ilo = ilo_context(pipe); 476 477 ilo->fs = state; 478 479 ilo->dirty |= ILO_DIRTY_FS; 480} 481 482static void 483ilo_delete_fs_state(struct pipe_context *pipe, void *state) 484{ 485 struct ilo_context *ilo = ilo_context(pipe); 486 struct ilo_shader_state *fs = (struct ilo_shader_state *) state; 487 488 ilo_shader_cache_remove(ilo->shader_cache, fs); 489 ilo_shader_destroy(fs); 490} 491 492static void * 493ilo_create_vs_state(struct pipe_context *pipe, 494 const struct pipe_shader_state *state) 495{ 496 struct ilo_context *ilo = ilo_context(pipe); 497 struct ilo_shader_state *shader; 498 499 shader = ilo_shader_create_vs(ilo->dev, state, ilo); 500 assert(shader); 501 502 ilo_shader_cache_add(ilo->shader_cache, shader); 503 504 return shader; 505} 506 507static void 508ilo_bind_vs_state(struct pipe_context *pipe, void *state) 509{ 510 struct ilo_context *ilo = ilo_context(pipe); 511 512 ilo->vs = state; 513 514 ilo->dirty |= ILO_DIRTY_VS; 515} 516 517static void 518ilo_delete_vs_state(struct pipe_context *pipe, void *state) 519{ 520 struct ilo_context *ilo = ilo_context(pipe); 521 struct ilo_shader_state *vs = (struct ilo_shader_state *) state; 522 523 ilo_shader_cache_remove(ilo->shader_cache, vs); 524 ilo_shader_destroy(vs); 525} 526 527static void * 528ilo_create_gs_state(struct pipe_context *pipe, 529 const struct pipe_shader_state *state) 530{ 531 struct ilo_context *ilo = ilo_context(pipe); 532 struct ilo_shader_state *shader; 533 534 shader = ilo_shader_create_gs(ilo->dev, state, ilo); 535 assert(shader); 536 537 ilo_shader_cache_add(ilo->shader_cache, shader); 538 539 return shader; 540} 541 542static void 543ilo_bind_gs_state(struct pipe_context *pipe, void *state) 544{ 545 struct ilo_context *ilo = ilo_context(pipe); 546 547 /* util_blitter may set this unnecessarily */ 548 if (ilo->gs == state) 549 return; 550 551 ilo->gs = state; 552 553 ilo->dirty |= ILO_DIRTY_GS; 554} 555 556static void 557ilo_delete_gs_state(struct pipe_context *pipe, void *state) 558{ 559 struct ilo_context *ilo = ilo_context(pipe); 560 struct ilo_shader_state *gs = (struct ilo_shader_state *) state; 561 562 ilo_shader_cache_remove(ilo->shader_cache, gs); 563 ilo_shader_destroy(gs); 564} 565 566static void * 567ilo_create_vertex_elements_state(struct pipe_context *pipe, 568 unsigned num_elements, 569 const struct pipe_vertex_element *elements) 570{ 571 struct ilo_context *ilo = ilo_context(pipe); 572 struct ilo_ve_state *ve; 573 574 ve = MALLOC_STRUCT(ilo_ve_state); 575 assert(ve); 576 577 ilo_gpe_init_ve(ilo->dev, num_elements, elements, ve); 578 579 return ve; 580} 581 582static void 583ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state) 584{ 585 struct ilo_context *ilo = ilo_context(pipe); 586 587 ilo->ve = state; 588 589 ilo->dirty |= ILO_DIRTY_VE; 590} 591 592static void 593ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state) 594{ 595 struct ilo_ve_state *ve = state; 596 597 FREE(ve); 598} 599 600static void 601ilo_set_blend_color(struct pipe_context *pipe, 602 const struct pipe_blend_color *state) 603{ 604 struct ilo_context *ilo = ilo_context(pipe); 605 606 ilo->blend_color = *state; 607 608 ilo->dirty |= ILO_DIRTY_BLEND_COLOR; 609} 610 611static void 612ilo_set_stencil_ref(struct pipe_context *pipe, 613 const struct pipe_stencil_ref *state) 614{ 615 struct ilo_context *ilo = ilo_context(pipe); 616 617 /* util_blitter may set this unnecessarily */ 618 if (!memcmp(&ilo->stencil_ref, state, sizeof(*state))) 619 return; 620 621 ilo->stencil_ref = *state; 622 623 ilo->dirty |= ILO_DIRTY_STENCIL_REF; 624} 625 626static void 627ilo_set_sample_mask(struct pipe_context *pipe, 628 unsigned sample_mask) 629{ 630 struct ilo_context *ilo = ilo_context(pipe); 631 632 /* util_blitter may set this unnecessarily */ 633 if (ilo->sample_mask == sample_mask) 634 return; 635 636 ilo->sample_mask = sample_mask; 637 638 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK; 639} 640 641static void 642ilo_set_clip_state(struct pipe_context *pipe, 643 const struct pipe_clip_state *state) 644{ 645 struct ilo_context *ilo = ilo_context(pipe); 646 647 ilo->clip = *state; 648 649 ilo->dirty |= ILO_DIRTY_CLIP; 650} 651 652static void 653ilo_set_constant_buffer(struct pipe_context *pipe, 654 uint shader, uint index, 655 struct pipe_constant_buffer *buf) 656{ 657 struct ilo_context *ilo = ilo_context(pipe); 658 struct ilo_cbuf_state *cbuf = &ilo->cbuf[shader]; 659 const unsigned count = 1; 660 unsigned i; 661 662 assert(shader < Elements(ilo->cbuf)); 663 assert(index + count <= Elements(ilo->cbuf[shader].cso)); 664 665 if (buf) { 666 for (i = 0; i < count; i++) { 667 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i]; 668 669 pipe_resource_reference(&cso->resource, buf[i].buffer); 670 671 if (buf[i].buffer) { 672 const enum pipe_format elem_format = 673 PIPE_FORMAT_R32G32B32A32_FLOAT; 674 675 ilo_gpe_init_view_surface_for_buffer(ilo->dev, 676 ilo_buffer(buf[i].buffer), 677 buf[i].buffer_offset, buf[i].buffer_size, 678 util_format_get_blocksize(elem_format), elem_format, 679 false, false, &cso->surface); 680 681 cso->user_buffer = NULL; 682 cso->user_buffer_size = 0; 683 684 cbuf->enabled_mask |= 1 << (index + i); 685 } 686 else if (buf[i].user_buffer) { 687 cso->surface.bo = NULL; 688 689 /* buffer_offset does not apply for user buffer */ 690 cso->user_buffer = buf[i].user_buffer; 691 cso->user_buffer_size = buf[i].buffer_size; 692 693 cbuf->enabled_mask |= 1 << (index + i); 694 } 695 else { 696 cso->surface.bo = NULL; 697 cso->user_buffer = NULL; 698 cso->user_buffer_size = 0; 699 700 cbuf->enabled_mask &= ~(1 << (index + i)); 701 } 702 } 703 } 704 else { 705 for (i = 0; i < count; i++) { 706 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i]; 707 708 pipe_resource_reference(&cso->resource, NULL); 709 cso->surface.bo = NULL; 710 cso->user_buffer = NULL; 711 cso->user_buffer_size = 0; 712 713 cbuf->enabled_mask &= ~(1 << (index + i)); 714 } 715 } 716 717 ilo->dirty |= ILO_DIRTY_CBUF; 718} 719 720static void 721ilo_set_framebuffer_state(struct pipe_context *pipe, 722 const struct pipe_framebuffer_state *state) 723{ 724 struct ilo_context *ilo = ilo_context(pipe); 725 726 util_copy_framebuffer_state(&ilo->fb.state, state); 727 728 if (state->nr_cbufs) 729 ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples; 730 else if (state->zsbuf) 731 ilo->fb.num_samples = state->zsbuf->texture->nr_samples; 732 else 733 ilo->fb.num_samples = 1; 734 735 if (!ilo->fb.num_samples) 736 ilo->fb.num_samples = 1; 737 738 ilo->dirty |= ILO_DIRTY_FB; 739} 740 741static void 742ilo_set_polygon_stipple(struct pipe_context *pipe, 743 const struct pipe_poly_stipple *state) 744{ 745 struct ilo_context *ilo = ilo_context(pipe); 746 747 ilo->poly_stipple = *state; 748 749 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE; 750} 751 752static void 753ilo_set_scissor_states(struct pipe_context *pipe, 754 unsigned start_slot, 755 unsigned num_scissors, 756 const struct pipe_scissor_state *scissors) 757{ 758 struct ilo_context *ilo = ilo_context(pipe); 759 760 ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors, 761 scissors, &ilo->scissor); 762 763 ilo->dirty |= ILO_DIRTY_SCISSOR; 764} 765 766static void 767ilo_set_viewport_states(struct pipe_context *pipe, 768 unsigned start_slot, 769 unsigned num_viewports, 770 const struct pipe_viewport_state *viewports) 771{ 772 struct ilo_context *ilo = ilo_context(pipe); 773 774 if (viewports) { 775 unsigned i; 776 777 for (i = 0; i < num_viewports; i++) { 778 ilo_gpe_set_viewport_cso(ilo->dev, &viewports[i], 779 &ilo->viewport.cso[start_slot + i]); 780 } 781 782 if (ilo->viewport.count < start_slot + num_viewports) 783 ilo->viewport.count = start_slot + num_viewports; 784 785 /* need to save viewport 0 for util_blitter */ 786 if (!start_slot && num_viewports) 787 ilo->viewport.viewport0 = viewports[0]; 788 } 789 else { 790 if (ilo->viewport.count <= start_slot + num_viewports && 791 ilo->viewport.count > start_slot) 792 ilo->viewport.count = start_slot; 793 } 794 795 ilo->dirty |= ILO_DIRTY_VIEWPORT; 796} 797 798static void 799ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader, 800 unsigned start, unsigned count, 801 struct pipe_sampler_view **views) 802{ 803 struct ilo_context *ilo = ilo_context(pipe); 804 struct ilo_view_state *dst = &ilo->view[shader]; 805 unsigned i; 806 807 assert(start + count <= Elements(dst->states)); 808 809 if (views) { 810 for (i = 0; i < count; i++) 811 pipe_sampler_view_reference(&dst->states[start + i], views[i]); 812 } 813 else { 814 for (i = 0; i < count; i++) 815 pipe_sampler_view_reference(&dst->states[start + i], NULL); 816 } 817 818 if (dst->count <= start + count) { 819 if (views) 820 count += start; 821 else 822 count = start; 823 824 while (count > 0 && !dst->states[count - 1]) 825 count--; 826 827 dst->count = count; 828 } 829} 830 831static void 832ilo_set_fragment_sampler_views(struct pipe_context *pipe, 833 unsigned num_views, 834 struct pipe_sampler_view **views) 835{ 836 struct ilo_context *ilo = ilo_context(pipe); 837 838 ilo_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num_views, views); 839 840 if (ilo->view[PIPE_SHADER_FRAGMENT].count > num_views) { 841 ilo_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, num_views, 842 ilo->view[PIPE_SHADER_FRAGMENT].count - num_views, NULL); 843 } 844 845 ilo->dirty |= ILO_DIRTY_VIEW_FS; 846} 847 848static void 849ilo_set_vertex_sampler_views(struct pipe_context *pipe, 850 unsigned num_views, 851 struct pipe_sampler_view **views) 852{ 853 struct ilo_context *ilo = ilo_context(pipe); 854 855 ilo_set_sampler_views(pipe, PIPE_SHADER_VERTEX, 0, num_views, views); 856 857 if (ilo->view[PIPE_SHADER_VERTEX].count > num_views) { 858 ilo_set_sampler_views(pipe, PIPE_SHADER_VERTEX, num_views, 859 ilo->view[PIPE_SHADER_VERTEX].count - num_views, NULL); 860 } 861 862 ilo->dirty |= ILO_DIRTY_VIEW_VS; 863} 864 865static void 866ilo_set_geometry_sampler_views(struct pipe_context *pipe, 867 unsigned num_views, 868 struct pipe_sampler_view **views) 869{ 870 struct ilo_context *ilo = ilo_context(pipe); 871 872 ilo_set_sampler_views(pipe, PIPE_SHADER_GEOMETRY, 0, num_views, views); 873 874 if (ilo->view[PIPE_SHADER_GEOMETRY].count > num_views) { 875 ilo_set_sampler_views(pipe, PIPE_SHADER_GEOMETRY, num_views, 876 ilo->view[PIPE_SHADER_GEOMETRY].count - num_views, NULL); 877 } 878 879 ilo->dirty |= ILO_DIRTY_VIEW_GS; 880} 881 882static void 883ilo_set_compute_sampler_views(struct pipe_context *pipe, 884 unsigned start_slot, unsigned num_views, 885 struct pipe_sampler_view **views) 886{ 887 struct ilo_context *ilo = ilo_context(pipe); 888 889 ilo_set_sampler_views(pipe, PIPE_SHADER_COMPUTE, 890 start_slot, num_views, views); 891 892 ilo->dirty |= ILO_DIRTY_VIEW_CS; 893} 894 895static void 896ilo_set_sampler_views2(struct pipe_context *pipe, unsigned shader, 897 unsigned start_slot, unsigned num_views, 898 struct pipe_sampler_view **views) 899{ 900 switch (shader) { 901 case PIPE_SHADER_VERTEX: 902 ilo_set_vertex_sampler_views(pipe, num_views, views); 903 break; 904 case PIPE_SHADER_GEOMETRY: 905 ilo_set_geometry_sampler_views(pipe, num_views, views); 906 break; 907 case PIPE_SHADER_FRAGMENT: 908 ilo_set_fragment_sampler_views(pipe, num_views, views); 909 break; 910 case PIPE_SHADER_COMPUTE: 911 ilo_set_compute_sampler_views(pipe, start_slot, num_views, views); 912 break; 913 } 914} 915 916 917static void 918ilo_set_shader_resources(struct pipe_context *pipe, 919 unsigned start, unsigned count, 920 struct pipe_surface **surfaces) 921{ 922 struct ilo_context *ilo = ilo_context(pipe); 923 struct ilo_resource_state *dst = &ilo->resource; 924 unsigned i; 925 926 assert(start + count <= Elements(dst->states)); 927 928 if (surfaces) { 929 for (i = 0; i < count; i++) 930 pipe_surface_reference(&dst->states[start + i], surfaces[i]); 931 } 932 else { 933 for (i = 0; i < count; i++) 934 pipe_surface_reference(&dst->states[start + i], NULL); 935 } 936 937 if (dst->count <= start + count) { 938 if (surfaces) 939 count += start; 940 else 941 count = start; 942 943 while (count > 0 && !dst->states[count - 1]) 944 count--; 945 946 dst->count = count; 947 } 948 949 ilo->dirty |= ILO_DIRTY_RESOURCE; 950} 951 952static void 953ilo_set_vertex_buffers(struct pipe_context *pipe, 954 unsigned start_slot, unsigned num_buffers, 955 const struct pipe_vertex_buffer *buffers) 956{ 957 struct ilo_context *ilo = ilo_context(pipe); 958 unsigned i; 959 960 /* no PIPE_CAP_USER_VERTEX_BUFFERS */ 961 if (buffers) { 962 for (i = 0; i < num_buffers; i++) 963 assert(!buffers[i].user_buffer); 964 } 965 966 util_set_vertex_buffers_mask(ilo->vb.states, 967 &ilo->vb.enabled_mask, buffers, start_slot, num_buffers); 968 969 ilo->dirty |= ILO_DIRTY_VB; 970} 971 972static void 973ilo_set_index_buffer(struct pipe_context *pipe, 974 const struct pipe_index_buffer *state) 975{ 976 struct ilo_context *ilo = ilo_context(pipe); 977 978 if (state) { 979 pipe_resource_reference(&ilo->ib.buffer, state->buffer); 980 ilo->ib.user_buffer = state->user_buffer; 981 ilo->ib.offset = state->offset; 982 ilo->ib.index_size = state->index_size; 983 } 984 else { 985 pipe_resource_reference(&ilo->ib.buffer, NULL); 986 ilo->ib.user_buffer = NULL; 987 ilo->ib.offset = 0; 988 ilo->ib.index_size = 0; 989 } 990 991 ilo->dirty |= ILO_DIRTY_IB; 992} 993 994static struct pipe_stream_output_target * 995ilo_create_stream_output_target(struct pipe_context *pipe, 996 struct pipe_resource *res, 997 unsigned buffer_offset, 998 unsigned buffer_size) 999{ 1000 struct pipe_stream_output_target *target; 1001 1002 target = MALLOC_STRUCT(pipe_stream_output_target); 1003 assert(target); 1004 1005 pipe_reference_init(&target->reference, 1); 1006 target->buffer = NULL; 1007 pipe_resource_reference(&target->buffer, res); 1008 target->context = pipe; 1009 target->buffer_offset = buffer_offset; 1010 target->buffer_size = buffer_size; 1011 1012 return target; 1013} 1014 1015static void 1016ilo_set_stream_output_targets(struct pipe_context *pipe, 1017 unsigned num_targets, 1018 struct pipe_stream_output_target **targets, 1019 unsigned append_bitmask) 1020{ 1021 struct ilo_context *ilo = ilo_context(pipe); 1022 unsigned i; 1023 1024 if (!targets) 1025 num_targets = 0; 1026 1027 /* util_blitter may set this unnecessarily */ 1028 if (!ilo->so.count && !num_targets) 1029 return; 1030 1031 for (i = 0; i < num_targets; i++) 1032 pipe_so_target_reference(&ilo->so.states[i], targets[i]); 1033 1034 for (; i < ilo->so.count; i++) 1035 pipe_so_target_reference(&ilo->so.states[i], NULL); 1036 1037 ilo->so.count = num_targets; 1038 ilo->so.append_bitmask = append_bitmask; 1039 1040 ilo->so.enabled = (ilo->so.count > 0); 1041 1042 ilo->dirty |= ILO_DIRTY_SO; 1043} 1044 1045static void 1046ilo_stream_output_target_destroy(struct pipe_context *pipe, 1047 struct pipe_stream_output_target *target) 1048{ 1049 pipe_resource_reference(&target->buffer, NULL); 1050 FREE(target); 1051} 1052 1053static struct pipe_sampler_view * 1054ilo_create_sampler_view(struct pipe_context *pipe, 1055 struct pipe_resource *res, 1056 const struct pipe_sampler_view *templ) 1057{ 1058 struct ilo_context *ilo = ilo_context(pipe); 1059 struct ilo_view_cso *view; 1060 1061 view = MALLOC_STRUCT(ilo_view_cso); 1062 assert(view); 1063 1064 view->base = *templ; 1065 pipe_reference_init(&view->base.reference, 1); 1066 view->base.texture = NULL; 1067 pipe_resource_reference(&view->base.texture, res); 1068 view->base.context = pipe; 1069 1070 if (res->target == PIPE_BUFFER) { 1071 const unsigned elem_size = util_format_get_blocksize(templ->format); 1072 const unsigned first_elem = templ->u.buf.first_element; 1073 const unsigned num_elems = templ->u.buf.last_element - first_elem + 1; 1074 1075 ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(res), 1076 first_elem * elem_size, num_elems * elem_size, 1077 elem_size, templ->format, false, false, &view->surface); 1078 } 1079 else { 1080 struct ilo_texture *tex = ilo_texture(res); 1081 1082 /* warn about degraded performance because of a missing binding flag */ 1083 if (tex->tiling == INTEL_TILING_NONE && 1084 !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) { 1085 ilo_warn("creating sampler view for a resource " 1086 "not created for sampling\n"); 1087 } 1088 1089 ilo_gpe_init_view_surface_for_texture(ilo->dev, tex, 1090 templ->format, 1091 templ->u.tex.first_level, 1092 templ->u.tex.last_level - templ->u.tex.first_level + 1, 1093 templ->u.tex.first_layer, 1094 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 1095 false, false, &view->surface); 1096 } 1097 1098 return &view->base; 1099} 1100 1101static void 1102ilo_sampler_view_destroy(struct pipe_context *pipe, 1103 struct pipe_sampler_view *view) 1104{ 1105 pipe_resource_reference(&view->texture, NULL); 1106 FREE(view); 1107} 1108 1109static struct pipe_surface * 1110ilo_create_surface(struct pipe_context *pipe, 1111 struct pipe_resource *res, 1112 const struct pipe_surface *templ) 1113{ 1114 struct ilo_context *ilo = ilo_context(pipe); 1115 struct ilo_surface_cso *surf; 1116 1117 surf = MALLOC_STRUCT(ilo_surface_cso); 1118 assert(surf); 1119 1120 surf->base = *templ; 1121 pipe_reference_init(&surf->base.reference, 1); 1122 surf->base.texture = NULL; 1123 pipe_resource_reference(&surf->base.texture, res); 1124 1125 surf->base.context = pipe; 1126 surf->base.width = u_minify(res->width0, templ->u.tex.level); 1127 surf->base.height = u_minify(res->height0, templ->u.tex.level); 1128 1129 surf->is_rt = !util_format_is_depth_or_stencil(templ->format); 1130 1131 if (surf->is_rt) { 1132 /* relax this? */ 1133 assert(res->target != PIPE_BUFFER); 1134 1135 /* 1136 * classic i965 sets render_cache_rw for constant buffers and sol 1137 * surfaces but not render buffers. Why? 1138 */ 1139 ilo_gpe_init_view_surface_for_texture(ilo->dev, ilo_texture(res), 1140 templ->format, templ->u.tex.level, 1, 1141 templ->u.tex.first_layer, 1142 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 1143 true, true, &surf->u.rt); 1144 } 1145 else { 1146 assert(res->target != PIPE_BUFFER); 1147 1148 ilo_gpe_init_zs_surface(ilo->dev, ilo_texture(res), 1149 templ->format, templ->u.tex.level, 1150 templ->u.tex.first_layer, 1151 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 1152 &surf->u.zs); 1153 } 1154 1155 return &surf->base; 1156} 1157 1158static void 1159ilo_surface_destroy(struct pipe_context *pipe, 1160 struct pipe_surface *surface) 1161{ 1162 pipe_resource_reference(&surface->texture, NULL); 1163 FREE(surface); 1164} 1165 1166static void * 1167ilo_create_compute_state(struct pipe_context *pipe, 1168 const struct pipe_compute_state *state) 1169{ 1170 struct ilo_context *ilo = ilo_context(pipe); 1171 struct ilo_shader_state *shader; 1172 1173 shader = ilo_shader_create_cs(ilo->dev, state, ilo); 1174 assert(shader); 1175 1176 ilo_shader_cache_add(ilo->shader_cache, shader); 1177 1178 return shader; 1179} 1180 1181static void 1182ilo_bind_compute_state(struct pipe_context *pipe, void *state) 1183{ 1184 struct ilo_context *ilo = ilo_context(pipe); 1185 1186 ilo->cs = state; 1187 1188 ilo->dirty |= ILO_DIRTY_CS; 1189} 1190 1191static void 1192ilo_delete_compute_state(struct pipe_context *pipe, void *state) 1193{ 1194 struct ilo_context *ilo = ilo_context(pipe); 1195 struct ilo_shader_state *cs = (struct ilo_shader_state *) state; 1196 1197 ilo_shader_cache_remove(ilo->shader_cache, cs); 1198 ilo_shader_destroy(cs); 1199} 1200 1201static void 1202ilo_set_compute_resources(struct pipe_context *pipe, 1203 unsigned start, unsigned count, 1204 struct pipe_surface **surfaces) 1205{ 1206 struct ilo_context *ilo = ilo_context(pipe); 1207 struct ilo_resource_state *dst = &ilo->cs_resource; 1208 unsigned i; 1209 1210 assert(start + count <= Elements(dst->states)); 1211 1212 if (surfaces) { 1213 for (i = 0; i < count; i++) 1214 pipe_surface_reference(&dst->states[start + i], surfaces[i]); 1215 } 1216 else { 1217 for (i = 0; i < count; i++) 1218 pipe_surface_reference(&dst->states[start + i], NULL); 1219 } 1220 1221 if (dst->count <= start + count) { 1222 if (surfaces) 1223 count += start; 1224 else 1225 count = start; 1226 1227 while (count > 0 && !dst->states[count - 1]) 1228 count--; 1229 1230 dst->count = count; 1231 } 1232 1233 ilo->dirty |= ILO_DIRTY_CS_RESOURCE; 1234} 1235 1236static void 1237ilo_set_global_binding(struct pipe_context *pipe, 1238 unsigned start, unsigned count, 1239 struct pipe_resource **resources, 1240 uint32_t **handles) 1241{ 1242 struct ilo_context *ilo = ilo_context(pipe); 1243 struct ilo_global_binding *dst = &ilo->global_binding; 1244 unsigned i; 1245 1246 assert(start + count <= Elements(dst->resources)); 1247 1248 if (resources) { 1249 for (i = 0; i < count; i++) 1250 pipe_resource_reference(&dst->resources[start + i], resources[i]); 1251 } 1252 else { 1253 for (i = 0; i < count; i++) 1254 pipe_resource_reference(&dst->resources[start + i], NULL); 1255 } 1256 1257 if (dst->count <= start + count) { 1258 if (resources) 1259 count += start; 1260 else 1261 count = start; 1262 1263 while (count > 0 && !dst->resources[count - 1]) 1264 count--; 1265 1266 dst->count = count; 1267 } 1268 1269 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING; 1270} 1271 1272/** 1273 * Initialize state-related functions. 1274 */ 1275void 1276ilo_init_state_functions(struct ilo_context *ilo) 1277{ 1278 STATIC_ASSERT(ILO_STATE_COUNT <= 32); 1279 1280 ilo->base.create_blend_state = ilo_create_blend_state; 1281 ilo->base.bind_blend_state = ilo_bind_blend_state; 1282 ilo->base.delete_blend_state = ilo_delete_blend_state; 1283 ilo->base.create_sampler_state = ilo_create_sampler_state; 1284 ilo->base.bind_sampler_states = ilo_bind_sampler_states2; 1285 ilo->base.delete_sampler_state = ilo_delete_sampler_state; 1286 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state; 1287 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state; 1288 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state; 1289 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state; 1290 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state; 1291 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state; 1292 ilo->base.create_fs_state = ilo_create_fs_state; 1293 ilo->base.bind_fs_state = ilo_bind_fs_state; 1294 ilo->base.delete_fs_state = ilo_delete_fs_state; 1295 ilo->base.create_vs_state = ilo_create_vs_state; 1296 ilo->base.bind_vs_state = ilo_bind_vs_state; 1297 ilo->base.delete_vs_state = ilo_delete_vs_state; 1298 ilo->base.create_gs_state = ilo_create_gs_state; 1299 ilo->base.bind_gs_state = ilo_bind_gs_state; 1300 ilo->base.delete_gs_state = ilo_delete_gs_state; 1301 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state; 1302 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state; 1303 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state; 1304 1305 ilo->base.set_blend_color = ilo_set_blend_color; 1306 ilo->base.set_stencil_ref = ilo_set_stencil_ref; 1307 ilo->base.set_sample_mask = ilo_set_sample_mask; 1308 ilo->base.set_clip_state = ilo_set_clip_state; 1309 ilo->base.set_constant_buffer = ilo_set_constant_buffer; 1310 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state; 1311 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple; 1312 ilo->base.set_scissor_states = ilo_set_scissor_states; 1313 ilo->base.set_viewport_states = ilo_set_viewport_states; 1314 ilo->base.set_sampler_views = ilo_set_sampler_views2; 1315 ilo->base.set_shader_resources = ilo_set_shader_resources; 1316 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers; 1317 ilo->base.set_index_buffer = ilo_set_index_buffer; 1318 1319 ilo->base.create_stream_output_target = ilo_create_stream_output_target; 1320 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy; 1321 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets; 1322 1323 ilo->base.create_sampler_view = ilo_create_sampler_view; 1324 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy; 1325 1326 ilo->base.create_surface = ilo_create_surface; 1327 ilo->base.surface_destroy = ilo_surface_destroy; 1328 1329 ilo->base.create_compute_state = ilo_create_compute_state; 1330 ilo->base.bind_compute_state = ilo_bind_compute_state; 1331 ilo->base.delete_compute_state = ilo_delete_compute_state; 1332 ilo->base.set_compute_resources = ilo_set_compute_resources; 1333 ilo->base.set_global_binding = ilo_set_global_binding; 1334} 1335 1336void 1337ilo_init_states(struct ilo_context *ilo) 1338{ 1339 ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor); 1340 1341 ilo_gpe_init_zs_surface(ilo->dev, NULL, 1342 PIPE_FORMAT_NONE, 0, 0, 1, &ilo->fb.null_zs); 1343 1344 ilo->dirty = ILO_DIRTY_ALL; 1345} 1346 1347void 1348ilo_cleanup_states(struct ilo_context *ilo) 1349{ 1350 unsigned i, sh; 1351 1352 for (i = 0; i < Elements(ilo->vb.states); i++) { 1353 if (ilo->vb.enabled_mask & (1 << i)) 1354 pipe_resource_reference(&ilo->vb.states[i].buffer, NULL); 1355 } 1356 1357 pipe_resource_reference(&ilo->ib.buffer, NULL); 1358 pipe_resource_reference(&ilo->ib.hw_resource, NULL); 1359 1360 for (i = 0; i < ilo->so.count; i++) 1361 pipe_so_target_reference(&ilo->so.states[i], NULL); 1362 1363 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 1364 for (i = 0; i < ilo->view[sh].count; i++) { 1365 struct pipe_sampler_view *view = ilo->view[sh].states[i]; 1366 pipe_sampler_view_reference(&view, NULL); 1367 } 1368 1369 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { 1370 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; 1371 pipe_resource_reference(&cbuf->resource, NULL); 1372 } 1373 } 1374 1375 for (i = 0; i < ilo->resource.count; i++) 1376 pipe_surface_reference(&ilo->resource.states[i], NULL); 1377 1378 for (i = 0; i < ilo->fb.state.nr_cbufs; i++) 1379 pipe_surface_reference(&ilo->fb.state.cbufs[i], NULL); 1380 1381 if (ilo->fb.state.zsbuf) 1382 pipe_surface_reference(&ilo->fb.state.zsbuf, NULL); 1383 1384 for (i = 0; i < ilo->cs_resource.count; i++) 1385 pipe_surface_reference(&ilo->cs_resource.states[i], NULL); 1386 1387 for (i = 0; i < ilo->global_binding.count; i++) 1388 pipe_resource_reference(&ilo->global_binding.resources[i], NULL); 1389} 1390 1391/** 1392 * Mark all states that have the resource dirty. 1393 */ 1394void 1395ilo_mark_states_with_resource_dirty(struct ilo_context *ilo, 1396 const struct pipe_resource *res) 1397{ 1398 uint32_t states = 0; 1399 unsigned sh, i; 1400 1401 if (res->target == PIPE_BUFFER) { 1402 uint32_t vb_mask = ilo->vb.enabled_mask; 1403 1404 while (vb_mask) { 1405 const unsigned idx = u_bit_scan(&vb_mask); 1406 1407 if (ilo->vb.states[idx].buffer == res) { 1408 states |= ILO_DIRTY_VB; 1409 break; 1410 } 1411 } 1412 1413 if (ilo->ib.buffer == res) { 1414 states |= ILO_DIRTY_IB; 1415 1416 /* 1417 * finalize_index_buffer() has an optimization that clears 1418 * ILO_DIRTY_IB when the HW states do not change. However, it fails 1419 * to flush the VF cache when the HW states do not change, but the 1420 * contents of the IB has changed. Here, we set the index size to an 1421 * invalid value to avoid the optimization. 1422 */ 1423 ilo->ib.hw_index_size = 0; 1424 } 1425 1426 for (i = 0; i < ilo->so.count; i++) { 1427 if (ilo->so.states[i]->buffer == res) { 1428 states |= ILO_DIRTY_SO; 1429 break; 1430 } 1431 } 1432 } 1433 1434 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 1435 for (i = 0; i < ilo->view[sh].count; i++) { 1436 struct pipe_sampler_view *view = ilo->view[sh].states[i]; 1437 1438 if (view->texture == res) { 1439 static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = { 1440 [PIPE_SHADER_VERTEX] = ILO_DIRTY_VIEW_VS, 1441 [PIPE_SHADER_FRAGMENT] = ILO_DIRTY_VIEW_FS, 1442 [PIPE_SHADER_GEOMETRY] = ILO_DIRTY_VIEW_GS, 1443 [PIPE_SHADER_COMPUTE] = ILO_DIRTY_VIEW_CS, 1444 }; 1445 1446 states |= view_dirty_bits[sh]; 1447 break; 1448 } 1449 } 1450 1451 if (res->target == PIPE_BUFFER) { 1452 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { 1453 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; 1454 1455 if (cbuf->resource == res) { 1456 states |= ILO_DIRTY_CBUF; 1457 break; 1458 } 1459 } 1460 } 1461 } 1462 1463 for (i = 0; i < ilo->resource.count; i++) { 1464 if (ilo->resource.states[i]->texture == res) { 1465 states |= ILO_DIRTY_RESOURCE; 1466 break; 1467 } 1468 } 1469 1470 /* for now? */ 1471 if (res->target != PIPE_BUFFER) { 1472 for (i = 0; i < ilo->fb.state.nr_cbufs; i++) { 1473 if (ilo->fb.state.cbufs[i]->texture == res) { 1474 states |= ILO_DIRTY_FB; 1475 break; 1476 } 1477 } 1478 1479 if (ilo->fb.state.zsbuf && ilo->fb.state.zsbuf->texture == res) 1480 states |= ILO_DIRTY_FB; 1481 } 1482 1483 for (i = 0; i < ilo->cs_resource.count; i++) { 1484 pipe_surface_reference(&ilo->cs_resource.states[i], NULL); 1485 if (ilo->cs_resource.states[i]->texture == res) { 1486 states |= ILO_DIRTY_CS_RESOURCE; 1487 break; 1488 } 1489 } 1490 1491 for (i = 0; i < ilo->global_binding.count; i++) { 1492 if (ilo->global_binding.resources[i] == res) { 1493 states |= ILO_DIRTY_GLOBAL_BINDING; 1494 break; 1495 } 1496 } 1497 1498 ilo->dirty |= states; 1499} 1500 1501void 1502ilo_dump_dirty_flags(uint32_t dirty) 1503{ 1504 static const char *state_names[ILO_STATE_COUNT] = { 1505 [ILO_STATE_VB] = "VB", 1506 [ILO_STATE_VE] = "VE", 1507 [ILO_STATE_IB] = "IB", 1508 [ILO_STATE_VS] = "VS", 1509 [ILO_STATE_GS] = "GS", 1510 [ILO_STATE_SO] = "SO", 1511 [ILO_STATE_CLIP] = "CLIP", 1512 [ILO_STATE_VIEWPORT] = "VIEWPORT", 1513 [ILO_STATE_SCISSOR] = "SCISSOR", 1514 [ILO_STATE_RASTERIZER] = "RASTERIZER", 1515 [ILO_STATE_POLY_STIPPLE] = "POLY_STIPPLE", 1516 [ILO_STATE_SAMPLE_MASK] = "SAMPLE_MASK", 1517 [ILO_STATE_FS] = "FS", 1518 [ILO_STATE_DSA] = "DSA", 1519 [ILO_STATE_STENCIL_REF] = "STENCIL_REF", 1520 [ILO_STATE_BLEND] = "BLEND", 1521 [ILO_STATE_BLEND_COLOR] = "BLEND_COLOR", 1522 [ILO_STATE_FB] = "FB", 1523 [ILO_STATE_SAMPLER_VS] = "SAMPLER_VS", 1524 [ILO_STATE_SAMPLER_GS] = "SAMPLER_GS", 1525 [ILO_STATE_SAMPLER_FS] = "SAMPLER_FS", 1526 [ILO_STATE_SAMPLER_CS] = "SAMPLER_CS", 1527 [ILO_STATE_VIEW_VS] = "VIEW_VS", 1528 [ILO_STATE_VIEW_GS] = "VIEW_GS", 1529 [ILO_STATE_VIEW_FS] = "VIEW_FS", 1530 [ILO_STATE_VIEW_CS] = "VIEW_CS", 1531 [ILO_STATE_CBUF] = "CBUF", 1532 [ILO_STATE_RESOURCE] = "RESOURCE", 1533 [ILO_STATE_CS] = "CS", 1534 [ILO_STATE_CS_RESOURCE] = "CS_RESOURCE", 1535 [ILO_STATE_GLOBAL_BINDING] = "GLOBAL_BINDING", 1536 }; 1537 1538 if (!dirty) { 1539 ilo_printf("no state is dirty\n"); 1540 return; 1541 } 1542 1543 dirty &= (1U << ILO_STATE_COUNT) - 1; 1544 1545 ilo_printf("%2d states are dirty:", util_bitcount(dirty)); 1546 while (dirty) { 1547 const enum ilo_state state = u_bit_scan(&dirty); 1548 ilo_printf(" %s", state_names[state]); 1549 } 1550 ilo_printf("\n"); 1551} 1552