ilo_state.c revision f0afedeb750d9f696242294c730827a28bdaac70
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 31#include "shader/ilo_shader_internal.h" 32#include "ilo_context.h" 33#include "ilo_resource.h" 34#include "ilo_shader.h" 35#include "ilo_state.h" 36 37/* 38 * We simply remember the pipe states here and derive HW commands/states from 39 * them later. We could do better by deriving (some of the) HW 40 * commands/states directly. 41 */ 42 43static void 44finalize_shader_states(struct ilo_context *ilo) 45{ 46 /* this table is ugly and is a burden to maintain.. */ 47 const struct { 48 struct ilo_shader_state *state; 49 struct ilo_shader *prev_shader; 50 uint32_t dirty; 51 uint32_t deps; 52 } sh[PIPE_SHADER_TYPES] = { 53 [PIPE_SHADER_VERTEX] = { 54 .state = ilo->vs, 55 .prev_shader = (ilo->vs) ? ilo->vs->shader : NULL, 56 .dirty = ILO_DIRTY_VS, 57 .deps = ILO_DIRTY_VERTEX_SAMPLER_VIEWS | 58 ILO_DIRTY_RASTERIZER, 59 }, 60 [PIPE_SHADER_FRAGMENT] = { 61 .state = ilo->fs, 62 .prev_shader = (ilo->fs) ? ilo->fs->shader : NULL, 63 .dirty = ILO_DIRTY_FS, 64 .deps = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS | 65 ILO_DIRTY_RASTERIZER | 66 ILO_DIRTY_FRAMEBUFFER, 67 }, 68 [PIPE_SHADER_GEOMETRY] = { 69 .state = ilo->gs, 70 .prev_shader = (ilo->gs) ? ilo->gs->shader : NULL, 71 .dirty = ILO_DIRTY_GS, 72 .deps = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS | 73 ILO_DIRTY_VS | 74 ILO_DIRTY_RASTERIZER, 75 }, 76 [PIPE_SHADER_COMPUTE] = { 77 .state = NULL, 78 .prev_shader = NULL, 79 .dirty = 0, 80 .deps = 0, 81 }, 82 }; 83 int i; 84 85 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 86 /* no state bound */ 87 if (!sh[i].state) 88 continue; 89 90 /* switch variant if the shader or the states it depends on changed */ 91 if (ilo->dirty & (sh[i].dirty | sh[i].deps)) { 92 struct ilo_shader_variant variant; 93 94 ilo_shader_variant_init(&variant, &sh[i].state->info, ilo); 95 ilo_shader_state_use_variant(sh[i].state, &variant); 96 } 97 } 98 99 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 100 /* no state bound */ 101 if (!sh[i].state) 102 continue; 103 104 /* mark the shader state dirty if new variant is selected */ 105 if (sh[i].state->shader != sh[i].prev_shader) 106 ilo->dirty |= sh[i].dirty; 107 } 108} 109 110static void 111finalize_constant_buffers(struct ilo_context *ilo) 112{ 113 int sh; 114 115 if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER)) 116 return; 117 118 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 119 int last_cbuf = Elements(ilo->cbuf[sh].cso) - 1; 120 121 /* find the last cbuf */ 122 while (last_cbuf >= 0 && 123 !ilo->cbuf[sh].cso[last_cbuf].resource) 124 last_cbuf--; 125 126 ilo->cbuf[sh].count = last_cbuf + 1; 127 } 128} 129 130/** 131 * Finalize states. Some states depend on other states and are 132 * incomplete/invalid until finalized. 133 */ 134void 135ilo_finalize_states(struct ilo_context *ilo) 136{ 137 finalize_shader_states(ilo); 138 finalize_constant_buffers(ilo); 139} 140 141static void * 142ilo_create_blend_state(struct pipe_context *pipe, 143 const struct pipe_blend_state *state) 144{ 145 struct ilo_context *ilo = ilo_context(pipe); 146 struct ilo_blend_state *blend; 147 148 blend = MALLOC_STRUCT(ilo_blend_state); 149 assert(blend); 150 151 ilo_gpe_init_blend(ilo->dev, state, blend); 152 153 return blend; 154} 155 156static void 157ilo_bind_blend_state(struct pipe_context *pipe, void *state) 158{ 159 struct ilo_context *ilo = ilo_context(pipe); 160 161 ilo->blend = state; 162 163 ilo->dirty |= ILO_DIRTY_BLEND; 164} 165 166static void 167ilo_delete_blend_state(struct pipe_context *pipe, void *state) 168{ 169 FREE(state); 170} 171 172static void * 173ilo_create_sampler_state(struct pipe_context *pipe, 174 const struct pipe_sampler_state *state) 175{ 176 struct ilo_context *ilo = ilo_context(pipe); 177 struct ilo_sampler_cso *sampler; 178 179 sampler = MALLOC_STRUCT(ilo_sampler_cso); 180 assert(sampler); 181 182 ilo_gpe_init_sampler_cso(ilo->dev, state, sampler); 183 184 return sampler; 185} 186 187static void 188bind_samplers(struct ilo_context *ilo, 189 unsigned shader, unsigned start, unsigned count, 190 void **samplers, bool unbind_old) 191{ 192 const struct ilo_sampler_cso **dst = ilo->sampler[shader].cso; 193 unsigned i; 194 195 assert(start + count <= Elements(ilo->sampler[shader].cso)); 196 197 if (unbind_old) { 198 if (!samplers) { 199 start = 0; 200 count = 0; 201 } 202 203 for (i = 0; i < start; i++) 204 dst[i] = NULL; 205 for (; i < start + count; i++) 206 dst[i] = samplers[i - start]; 207 for (; i < ilo->sampler[shader].count; i++) 208 dst[i] = NULL; 209 210 ilo->sampler[shader].count = start + count; 211 212 return; 213 } 214 215 dst += start; 216 if (samplers) { 217 for (i = 0; i < count; i++) 218 dst[i] = samplers[i]; 219 } 220 else { 221 for (i = 0; i < count; i++) 222 dst[i] = NULL; 223 } 224 225 if (ilo->sampler[shader].count <= start + count) { 226 count += start; 227 228 while (count > 0 && !ilo->sampler[shader].cso[count - 1]) 229 count--; 230 231 ilo->sampler[shader].count = count; 232 } 233} 234 235static void 236ilo_bind_fragment_sampler_states(struct pipe_context *pipe, 237 unsigned num_samplers, 238 void **samplers) 239{ 240 struct ilo_context *ilo = ilo_context(pipe); 241 242 bind_samplers(ilo, PIPE_SHADER_FRAGMENT, 0, num_samplers, samplers, true); 243 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLERS; 244} 245 246static void 247ilo_bind_vertex_sampler_states(struct pipe_context *pipe, 248 unsigned num_samplers, 249 void **samplers) 250{ 251 struct ilo_context *ilo = ilo_context(pipe); 252 253 bind_samplers(ilo, PIPE_SHADER_VERTEX, 0, num_samplers, samplers, true); 254 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLERS; 255} 256 257static void 258ilo_bind_geometry_sampler_states(struct pipe_context *pipe, 259 unsigned num_samplers, 260 void **samplers) 261{ 262 struct ilo_context *ilo = ilo_context(pipe); 263 264 bind_samplers(ilo, PIPE_SHADER_GEOMETRY, 0, num_samplers, samplers, true); 265 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLERS; 266} 267 268static void 269ilo_bind_compute_sampler_states(struct pipe_context *pipe, 270 unsigned start_slot, 271 unsigned num_samplers, 272 void **samplers) 273{ 274 struct ilo_context *ilo = ilo_context(pipe); 275 276 bind_samplers(ilo, PIPE_SHADER_COMPUTE, 277 start_slot, num_samplers, samplers, false); 278 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLERS; 279} 280 281static void 282ilo_delete_sampler_state(struct pipe_context *pipe, void *state) 283{ 284 FREE(state); 285} 286 287static void * 288ilo_create_rasterizer_state(struct pipe_context *pipe, 289 const struct pipe_rasterizer_state *state) 290{ 291 struct ilo_context *ilo = ilo_context(pipe); 292 struct ilo_rasterizer_state *rast; 293 294 rast = MALLOC_STRUCT(ilo_rasterizer_state); 295 assert(rast); 296 297 rast->state = *state; 298 ilo_gpe_init_rasterizer(ilo->dev, state, rast); 299 300 return rast; 301} 302 303static void 304ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state) 305{ 306 struct ilo_context *ilo = ilo_context(pipe); 307 308 ilo->rasterizer = state; 309 310 ilo->dirty |= ILO_DIRTY_RASTERIZER; 311} 312 313static void 314ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state) 315{ 316 FREE(state); 317} 318 319static void * 320ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe, 321 const struct pipe_depth_stencil_alpha_state *state) 322{ 323 struct ilo_context *ilo = ilo_context(pipe); 324 struct ilo_dsa_state *dsa; 325 326 dsa = MALLOC_STRUCT(ilo_dsa_state); 327 assert(dsa); 328 329 ilo_gpe_init_dsa(ilo->dev, state, dsa); 330 331 return dsa; 332} 333 334static void 335ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 336{ 337 struct ilo_context *ilo = ilo_context(pipe); 338 339 ilo->dsa = state; 340 341 ilo->dirty |= ILO_DIRTY_DEPTH_STENCIL_ALPHA; 342} 343 344static void 345ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 346{ 347 FREE(state); 348} 349 350static void * 351ilo_create_fs_state(struct pipe_context *pipe, 352 const struct pipe_shader_state *state) 353{ 354 struct ilo_context *ilo = ilo_context(pipe); 355 struct ilo_shader_state *shader; 356 357 shader = ilo_shader_create_fs(ilo->dev, state, ilo); 358 assert(shader); 359 360 ilo_shader_cache_add(ilo->shader_cache, shader); 361 362 return shader; 363} 364 365static void 366ilo_bind_fs_state(struct pipe_context *pipe, void *state) 367{ 368 struct ilo_context *ilo = ilo_context(pipe); 369 370 ilo->fs = state; 371 372 ilo->dirty |= ILO_DIRTY_FS; 373} 374 375static void 376ilo_delete_fs_state(struct pipe_context *pipe, void *state) 377{ 378 struct ilo_context *ilo = ilo_context(pipe); 379 struct ilo_shader_state *fs = (struct ilo_shader_state *) state; 380 381 ilo_shader_cache_remove(ilo->shader_cache, fs); 382 ilo_shader_destroy(fs); 383} 384 385static void * 386ilo_create_vs_state(struct pipe_context *pipe, 387 const struct pipe_shader_state *state) 388{ 389 struct ilo_context *ilo = ilo_context(pipe); 390 struct ilo_shader_state *shader; 391 392 shader = ilo_shader_create_vs(ilo->dev, state, ilo); 393 assert(shader); 394 395 ilo_shader_cache_add(ilo->shader_cache, shader); 396 397 return shader; 398} 399 400static void 401ilo_bind_vs_state(struct pipe_context *pipe, void *state) 402{ 403 struct ilo_context *ilo = ilo_context(pipe); 404 405 ilo->vs = state; 406 407 ilo->dirty |= ILO_DIRTY_VS; 408} 409 410static void 411ilo_delete_vs_state(struct pipe_context *pipe, void *state) 412{ 413 struct ilo_context *ilo = ilo_context(pipe); 414 struct ilo_shader_state *vs = (struct ilo_shader_state *) state; 415 416 ilo_shader_cache_remove(ilo->shader_cache, vs); 417 ilo_shader_destroy(vs); 418} 419 420static void * 421ilo_create_gs_state(struct pipe_context *pipe, 422 const struct pipe_shader_state *state) 423{ 424 struct ilo_context *ilo = ilo_context(pipe); 425 struct ilo_shader_state *shader; 426 427 shader = ilo_shader_create_gs(ilo->dev, state, ilo); 428 assert(shader); 429 430 ilo_shader_cache_add(ilo->shader_cache, shader); 431 432 return shader; 433} 434 435static void 436ilo_bind_gs_state(struct pipe_context *pipe, void *state) 437{ 438 struct ilo_context *ilo = ilo_context(pipe); 439 440 ilo->gs = state; 441 442 ilo->dirty |= ILO_DIRTY_GS; 443} 444 445static void 446ilo_delete_gs_state(struct pipe_context *pipe, void *state) 447{ 448 struct ilo_context *ilo = ilo_context(pipe); 449 struct ilo_shader_state *gs = (struct ilo_shader_state *) state; 450 451 ilo_shader_cache_remove(ilo->shader_cache, gs); 452 ilo_shader_destroy(gs); 453} 454 455static void * 456ilo_create_vertex_elements_state(struct pipe_context *pipe, 457 unsigned num_elements, 458 const struct pipe_vertex_element *elements) 459{ 460 struct ilo_context *ilo = ilo_context(pipe); 461 struct ilo_ve_state *ve; 462 463 ve = MALLOC_STRUCT(ilo_ve_state); 464 assert(ve); 465 466 ilo_gpe_init_ve(ilo->dev, num_elements, elements, ve); 467 468 return ve; 469} 470 471static void 472ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state) 473{ 474 struct ilo_context *ilo = ilo_context(pipe); 475 476 ilo->ve = state; 477 478 ilo->dirty |= ILO_DIRTY_VERTEX_ELEMENTS; 479} 480 481static void 482ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state) 483{ 484 struct ilo_ve_state *ve = state; 485 486 FREE(ve); 487} 488 489static void 490ilo_set_blend_color(struct pipe_context *pipe, 491 const struct pipe_blend_color *state) 492{ 493 struct ilo_context *ilo = ilo_context(pipe); 494 495 ilo->blend_color = *state; 496 497 ilo->dirty |= ILO_DIRTY_BLEND_COLOR; 498} 499 500static void 501ilo_set_stencil_ref(struct pipe_context *pipe, 502 const struct pipe_stencil_ref *state) 503{ 504 struct ilo_context *ilo = ilo_context(pipe); 505 506 ilo->stencil_ref = *state; 507 508 ilo->dirty |= ILO_DIRTY_STENCIL_REF; 509} 510 511static void 512ilo_set_sample_mask(struct pipe_context *pipe, 513 unsigned sample_mask) 514{ 515 struct ilo_context *ilo = ilo_context(pipe); 516 517 ilo->sample_mask = sample_mask; 518 519 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK; 520} 521 522static void 523ilo_set_clip_state(struct pipe_context *pipe, 524 const struct pipe_clip_state *state) 525{ 526 struct ilo_context *ilo = ilo_context(pipe); 527 528 ilo->clip = *state; 529 530 ilo->dirty |= ILO_DIRTY_CLIP; 531} 532 533static void 534ilo_set_constant_buffer(struct pipe_context *pipe, 535 uint shader, uint index, 536 struct pipe_constant_buffer *buf) 537{ 538 struct ilo_context *ilo = ilo_context(pipe); 539 struct ilo_cbuf_cso *cbuf; 540 541 assert(shader < Elements(ilo->cbuf)); 542 assert(index < Elements(ilo->cbuf[shader].cso)); 543 544 cbuf = &ilo->cbuf[shader].cso[index]; 545 546 if (buf) { 547 const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 548 549 /* no PIPE_CAP_USER_CONSTANT_BUFFERS */ 550 assert(!buf->user_buffer); 551 552 pipe_resource_reference(&cbuf->resource, buf->buffer); 553 554 ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(buf->buffer), 555 buf->buffer_offset, buf->buffer_size, 556 util_format_get_blocksize(elem_format), elem_format, 557 false, false, &cbuf->surface); 558 } 559 else { 560 pipe_resource_reference(&cbuf->resource, NULL); 561 cbuf->surface.bo = NULL; 562 } 563 564 /* the correct value will be set in ilo_finalize_states() */ 565 ilo->cbuf[shader].count = 0; 566 567 ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER; 568} 569 570static void 571ilo_set_framebuffer_state(struct pipe_context *pipe, 572 const struct pipe_framebuffer_state *state) 573{ 574 struct ilo_context *ilo = ilo_context(pipe); 575 576 util_copy_framebuffer_state(&ilo->fb.state, state); 577 578 if (state->nr_cbufs) 579 ilo->fb.num_samples = state->cbufs[0]->texture->nr_samples; 580 else if (state->zsbuf) 581 ilo->fb.num_samples = state->zsbuf->texture->nr_samples; 582 else 583 ilo->fb.num_samples = 1; 584 585 if (!ilo->fb.num_samples) 586 ilo->fb.num_samples = 1; 587 588 ilo->dirty |= ILO_DIRTY_FRAMEBUFFER; 589} 590 591static void 592ilo_set_polygon_stipple(struct pipe_context *pipe, 593 const struct pipe_poly_stipple *state) 594{ 595 struct ilo_context *ilo = ilo_context(pipe); 596 597 ilo->poly_stipple = *state; 598 599 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE; 600} 601 602static void 603ilo_set_scissor_states(struct pipe_context *pipe, 604 unsigned start_slot, 605 unsigned num_scissors, 606 const struct pipe_scissor_state *scissors) 607{ 608 struct ilo_context *ilo = ilo_context(pipe); 609 610 ilo_gpe_set_scissor(ilo->dev, start_slot, num_scissors, 611 scissors, &ilo->scissor); 612 613 ilo->dirty |= ILO_DIRTY_SCISSOR; 614} 615 616static void 617ilo_set_viewport_states(struct pipe_context *pipe, 618 unsigned start_slot, 619 unsigned num_viewports, 620 const struct pipe_viewport_state *viewports) 621{ 622 struct ilo_context *ilo = ilo_context(pipe); 623 624 if (viewports) { 625 unsigned i; 626 627 for (i = 0; i < num_viewports; i++) { 628 ilo_gpe_set_viewport_cso(ilo->dev, &viewports[i], 629 &ilo->viewport.cso[start_slot + i]); 630 } 631 632 if (ilo->viewport.count < start_slot + num_viewports) 633 ilo->viewport.count = start_slot + num_viewports; 634 635 /* need to save viewport 0 for util_blitter */ 636 if (!start_slot && num_viewports) 637 ilo->viewport.viewport0 = viewports[0]; 638 } 639 else { 640 if (ilo->viewport.count <= start_slot + num_viewports && 641 ilo->viewport.count > start_slot) 642 ilo->viewport.count = start_slot; 643 } 644 645 ilo->dirty |= ILO_DIRTY_VIEWPORT; 646} 647 648static void 649set_sampler_views(struct ilo_context *ilo, 650 unsigned shader, unsigned start, unsigned count, 651 struct pipe_sampler_view **views, bool unset_old) 652{ 653 struct pipe_sampler_view **dst = ilo->view[shader].states; 654 unsigned i; 655 656 assert(start + count <= Elements(ilo->view[shader].states)); 657 658 if (unset_old) { 659 if (!views) { 660 start = 0; 661 count = 0; 662 } 663 664 for (i = 0; i < start; i++) 665 pipe_sampler_view_reference(&dst[i], NULL); 666 for (; i < start + count; i++) 667 pipe_sampler_view_reference(&dst[i], views[i - start]); 668 for (; i < ilo->view[shader].count; i++) 669 pipe_sampler_view_reference(&dst[i], NULL); 670 671 ilo->view[shader].count = start + count; 672 673 return; 674 } 675 676 dst += start; 677 if (views) { 678 for (i = 0; i < count; i++) 679 pipe_sampler_view_reference(&dst[i], views[i]); 680 } 681 else { 682 for (i = 0; i < count; i++) 683 pipe_sampler_view_reference(&dst[i], NULL); 684 } 685 686 if (ilo->view[shader].count <= start + count) { 687 count += start; 688 689 while (count > 0 && !ilo->view[shader].states[count - 1]) 690 count--; 691 692 ilo->view[shader].count = count; 693 } 694} 695 696static void 697ilo_set_fragment_sampler_views(struct pipe_context *pipe, 698 unsigned num_views, 699 struct pipe_sampler_view **views) 700{ 701 struct ilo_context *ilo = ilo_context(pipe); 702 703 set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true); 704 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS; 705} 706 707static void 708ilo_set_vertex_sampler_views(struct pipe_context *pipe, 709 unsigned num_views, 710 struct pipe_sampler_view **views) 711{ 712 struct ilo_context *ilo = ilo_context(pipe); 713 714 set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true); 715 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS; 716} 717 718static void 719ilo_set_geometry_sampler_views(struct pipe_context *pipe, 720 unsigned num_views, 721 struct pipe_sampler_view **views) 722{ 723 struct ilo_context *ilo = ilo_context(pipe); 724 725 set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true); 726 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS; 727} 728 729static void 730ilo_set_compute_sampler_views(struct pipe_context *pipe, 731 unsigned start_slot, unsigned num_views, 732 struct pipe_sampler_view **views) 733{ 734 struct ilo_context *ilo = ilo_context(pipe); 735 736 set_sampler_views(ilo, PIPE_SHADER_COMPUTE, 737 start_slot, num_views, views, false); 738 739 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS; 740} 741 742static void 743ilo_set_shader_resources(struct pipe_context *pipe, 744 unsigned start, unsigned count, 745 struct pipe_surface **surfaces) 746{ 747 struct ilo_context *ilo = ilo_context(pipe); 748 struct pipe_surface **dst = ilo->resource.states; 749 unsigned i; 750 751 assert(start + count <= Elements(ilo->resource.states)); 752 753 dst += start; 754 if (surfaces) { 755 for (i = 0; i < count; i++) 756 pipe_surface_reference(&dst[i], surfaces[i]); 757 } 758 else { 759 for (i = 0; i < count; i++) 760 pipe_surface_reference(&dst[i], NULL); 761 } 762 763 if (ilo->resource.count <= start + count) { 764 count += start; 765 766 while (count > 0 && !ilo->resource.states[count - 1]) 767 count--; 768 769 ilo->resource.count = count; 770 } 771 772 ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES; 773} 774 775static void 776ilo_set_vertex_buffers(struct pipe_context *pipe, 777 unsigned start_slot, unsigned num_buffers, 778 const struct pipe_vertex_buffer *buffers) 779{ 780 struct ilo_context *ilo = ilo_context(pipe); 781 unsigned i; 782 783 /* no PIPE_CAP_USER_VERTEX_BUFFERS */ 784 if (buffers) { 785 for (i = 0; i < num_buffers; i++) 786 assert(!buffers[i].user_buffer); 787 } 788 789 util_set_vertex_buffers_mask(ilo->vb.states, 790 &ilo->vb.enabled_mask, buffers, start_slot, num_buffers); 791 792 ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS; 793} 794 795static void 796ilo_set_index_buffer(struct pipe_context *pipe, 797 const struct pipe_index_buffer *state) 798{ 799 struct ilo_context *ilo = ilo_context(pipe); 800 801 if (state) { 802 /* no PIPE_CAP_USER_INDEX_BUFFERS */ 803 assert(!state->user_buffer); 804 805 ilo->ib.state.index_size = state->index_size; 806 ilo->ib.state.offset = state->offset; 807 pipe_resource_reference(&ilo->ib.state.buffer, state->buffer); 808 ilo->ib.state.user_buffer = state->user_buffer; 809 } 810 else { 811 ilo->ib.state.index_size = 0; 812 ilo->ib.state.offset = 0; 813 pipe_resource_reference(&ilo->ib.state.buffer, NULL); 814 ilo->ib.state.user_buffer = NULL; 815 } 816 817 ilo->dirty |= ILO_DIRTY_INDEX_BUFFER; 818} 819 820static struct pipe_stream_output_target * 821ilo_create_stream_output_target(struct pipe_context *pipe, 822 struct pipe_resource *res, 823 unsigned buffer_offset, 824 unsigned buffer_size) 825{ 826 struct pipe_stream_output_target *target; 827 828 target = MALLOC_STRUCT(pipe_stream_output_target); 829 assert(target); 830 831 pipe_reference_init(&target->reference, 1); 832 target->buffer = NULL; 833 pipe_resource_reference(&target->buffer, res); 834 target->context = pipe; 835 target->buffer_offset = buffer_offset; 836 target->buffer_size = buffer_size; 837 838 return target; 839} 840 841static void 842ilo_set_stream_output_targets(struct pipe_context *pipe, 843 unsigned num_targets, 844 struct pipe_stream_output_target **targets, 845 unsigned append_bitmask) 846{ 847 struct ilo_context *ilo = ilo_context(pipe); 848 unsigned i; 849 850 if (!targets) 851 num_targets = 0; 852 853 for (i = 0; i < num_targets; i++) 854 pipe_so_target_reference(&ilo->so.states[i], targets[i]); 855 856 for (; i < ilo->so.count; i++) 857 pipe_so_target_reference(&ilo->so.states[i], NULL); 858 859 ilo->so.count = num_targets; 860 ilo->so.append_bitmask = append_bitmask; 861 862 ilo->so.enabled = (ilo->so.count > 0); 863 864 ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS; 865} 866 867static void 868ilo_stream_output_target_destroy(struct pipe_context *pipe, 869 struct pipe_stream_output_target *target) 870{ 871 pipe_resource_reference(&target->buffer, NULL); 872 FREE(target); 873} 874 875static struct pipe_sampler_view * 876ilo_create_sampler_view(struct pipe_context *pipe, 877 struct pipe_resource *res, 878 const struct pipe_sampler_view *templ) 879{ 880 struct ilo_context *ilo = ilo_context(pipe); 881 struct ilo_view_cso *view; 882 883 view = MALLOC_STRUCT(ilo_view_cso); 884 assert(view); 885 886 view->base = *templ; 887 pipe_reference_init(&view->base.reference, 1); 888 view->base.texture = NULL; 889 pipe_resource_reference(&view->base.texture, res); 890 view->base.context = pipe; 891 892 if (res->target == PIPE_BUFFER) { 893 const unsigned elem_size = util_format_get_blocksize(templ->format); 894 const unsigned first_elem = templ->u.buf.first_element; 895 const unsigned num_elems = templ->u.buf.last_element - first_elem + 1; 896 897 ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(res), 898 first_elem * elem_size, num_elems * elem_size, 899 elem_size, templ->format, false, false, &view->surface); 900 } 901 else { 902 struct ilo_texture *tex = ilo_texture(res); 903 904 /* warn about degraded performance because of a missing binding flag */ 905 if (tex->tiling == INTEL_TILING_NONE && 906 !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) { 907 ilo_warn("creating sampler view for a resource " 908 "not created for sampling\n"); 909 } 910 911 ilo_gpe_init_view_surface_for_texture(ilo->dev, tex, 912 templ->format, 913 templ->u.tex.first_level, 914 templ->u.tex.last_level - templ->u.tex.first_level + 1, 915 templ->u.tex.first_layer, 916 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 917 false, false, &view->surface); 918 } 919 920 return &view->base; 921} 922 923static void 924ilo_sampler_view_destroy(struct pipe_context *pipe, 925 struct pipe_sampler_view *view) 926{ 927 pipe_resource_reference(&view->texture, NULL); 928 FREE(view); 929} 930 931static struct pipe_surface * 932ilo_create_surface(struct pipe_context *pipe, 933 struct pipe_resource *res, 934 const struct pipe_surface *templ) 935{ 936 struct ilo_context *ilo = ilo_context(pipe); 937 struct ilo_surface_cso *surf; 938 939 surf = MALLOC_STRUCT(ilo_surface_cso); 940 assert(surf); 941 942 surf->base = *templ; 943 pipe_reference_init(&surf->base.reference, 1); 944 surf->base.texture = NULL; 945 pipe_resource_reference(&surf->base.texture, res); 946 947 surf->base.context = pipe; 948 surf->base.width = u_minify(res->width0, templ->u.tex.level); 949 surf->base.height = u_minify(res->height0, templ->u.tex.level); 950 951 surf->is_rt = !util_format_is_depth_or_stencil(templ->format); 952 953 if (surf->is_rt) { 954 /* relax this? */ 955 assert(res->target != PIPE_BUFFER); 956 957 /* 958 * classic i965 sets render_cache_rw for constant buffers and sol 959 * surfaces but not render buffers. Why? 960 */ 961 ilo_gpe_init_view_surface_for_texture(ilo->dev, ilo_texture(res), 962 templ->format, templ->u.tex.level, 1, 963 templ->u.tex.first_layer, 964 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 965 true, true, &surf->u.rt); 966 } 967 else { 968 assert(res->target != PIPE_BUFFER); 969 970 ilo_gpe_init_zs_surface(ilo->dev, ilo_texture(res), 971 templ->format, templ->u.tex.level, 972 templ->u.tex.first_layer, 973 templ->u.tex.last_layer - templ->u.tex.first_layer + 1, 974 &surf->u.zs); 975 } 976 977 return &surf->base; 978} 979 980static void 981ilo_surface_destroy(struct pipe_context *pipe, 982 struct pipe_surface *surface) 983{ 984 pipe_resource_reference(&surface->texture, NULL); 985 FREE(surface); 986} 987 988static void * 989ilo_create_compute_state(struct pipe_context *pipe, 990 const struct pipe_compute_state *state) 991{ 992 struct ilo_context *ilo = ilo_context(pipe); 993 struct ilo_shader_state *shader; 994 995 shader = ilo_shader_create_cs(ilo->dev, state, ilo); 996 assert(shader); 997 998 ilo_shader_cache_add(ilo->shader_cache, shader); 999 1000 return shader; 1001} 1002 1003static void 1004ilo_bind_compute_state(struct pipe_context *pipe, void *state) 1005{ 1006 struct ilo_context *ilo = ilo_context(pipe); 1007 1008 ilo->cs = state; 1009 1010 ilo->dirty |= ILO_DIRTY_COMPUTE; 1011} 1012 1013static void 1014ilo_delete_compute_state(struct pipe_context *pipe, void *state) 1015{ 1016 struct ilo_context *ilo = ilo_context(pipe); 1017 struct ilo_shader_state *cs = (struct ilo_shader_state *) state; 1018 1019 ilo_shader_cache_remove(ilo->shader_cache, cs); 1020 ilo_shader_destroy(cs); 1021} 1022 1023static void 1024ilo_set_compute_resources(struct pipe_context *pipe, 1025 unsigned start, unsigned count, 1026 struct pipe_surface **surfaces) 1027{ 1028 struct ilo_context *ilo = ilo_context(pipe); 1029 struct pipe_surface **dst = ilo->cs_resource.states; 1030 unsigned i; 1031 1032 assert(start + count <= Elements(ilo->cs_resource.states)); 1033 1034 dst += start; 1035 if (surfaces) { 1036 for (i = 0; i < count; i++) 1037 pipe_surface_reference(&dst[i], surfaces[i]); 1038 } 1039 else { 1040 for (i = 0; i < count; i++) 1041 pipe_surface_reference(&dst[i], NULL); 1042 } 1043 1044 if (ilo->cs_resource.count <= start + count) { 1045 count += start; 1046 1047 while (count > 0 && !ilo->cs_resource.states[count - 1]) 1048 count--; 1049 1050 ilo->cs_resource.count = count; 1051 } 1052 1053 ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES; 1054} 1055 1056static void 1057ilo_set_global_binding(struct pipe_context *pipe, 1058 unsigned start, unsigned count, 1059 struct pipe_resource **resources, 1060 uint32_t **handles) 1061{ 1062 struct ilo_context *ilo = ilo_context(pipe); 1063 struct pipe_resource **dst = ilo->global_binding.resources; 1064 unsigned i; 1065 1066 assert(start + count <= Elements(ilo->global_binding.resources)); 1067 1068 dst += start; 1069 if (resources) { 1070 for (i = 0; i < count; i++) 1071 pipe_resource_reference(&dst[i], resources[i]); 1072 } 1073 else { 1074 for (i = 0; i < count; i++) 1075 pipe_resource_reference(&dst[i], NULL); 1076 } 1077 1078 if (ilo->global_binding.count <= start + count) { 1079 count += start; 1080 1081 while (count > 0 && !ilo->global_binding.resources[count - 1]) 1082 count--; 1083 1084 ilo->global_binding.count = count; 1085 } 1086 1087 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING; 1088} 1089 1090/** 1091 * Initialize state-related functions. 1092 */ 1093void 1094ilo_init_state_functions(struct ilo_context *ilo) 1095{ 1096 STATIC_ASSERT(ILO_STATE_COUNT <= 32); 1097 1098 ilo->base.create_blend_state = ilo_create_blend_state; 1099 ilo->base.bind_blend_state = ilo_bind_blend_state; 1100 ilo->base.delete_blend_state = ilo_delete_blend_state; 1101 ilo->base.create_sampler_state = ilo_create_sampler_state; 1102 ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states; 1103 ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states; 1104 ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states; 1105 ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states; 1106 ilo->base.delete_sampler_state = ilo_delete_sampler_state; 1107 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state; 1108 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state; 1109 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state; 1110 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state; 1111 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state; 1112 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state; 1113 ilo->base.create_fs_state = ilo_create_fs_state; 1114 ilo->base.bind_fs_state = ilo_bind_fs_state; 1115 ilo->base.delete_fs_state = ilo_delete_fs_state; 1116 ilo->base.create_vs_state = ilo_create_vs_state; 1117 ilo->base.bind_vs_state = ilo_bind_vs_state; 1118 ilo->base.delete_vs_state = ilo_delete_vs_state; 1119 ilo->base.create_gs_state = ilo_create_gs_state; 1120 ilo->base.bind_gs_state = ilo_bind_gs_state; 1121 ilo->base.delete_gs_state = ilo_delete_gs_state; 1122 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state; 1123 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state; 1124 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state; 1125 1126 ilo->base.set_blend_color = ilo_set_blend_color; 1127 ilo->base.set_stencil_ref = ilo_set_stencil_ref; 1128 ilo->base.set_sample_mask = ilo_set_sample_mask; 1129 ilo->base.set_clip_state = ilo_set_clip_state; 1130 ilo->base.set_constant_buffer = ilo_set_constant_buffer; 1131 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state; 1132 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple; 1133 ilo->base.set_scissor_states = ilo_set_scissor_states; 1134 ilo->base.set_viewport_states = ilo_set_viewport_states; 1135 ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views; 1136 ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views; 1137 ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views; 1138 ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views; 1139 ilo->base.set_shader_resources = ilo_set_shader_resources; 1140 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers; 1141 ilo->base.set_index_buffer = ilo_set_index_buffer; 1142 1143 ilo->base.create_stream_output_target = ilo_create_stream_output_target; 1144 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy; 1145 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets; 1146 1147 ilo->base.create_sampler_view = ilo_create_sampler_view; 1148 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy; 1149 1150 ilo->base.create_surface = ilo_create_surface; 1151 ilo->base.surface_destroy = ilo_surface_destroy; 1152 1153 ilo->base.create_compute_state = ilo_create_compute_state; 1154 ilo->base.bind_compute_state = ilo_bind_compute_state; 1155 ilo->base.delete_compute_state = ilo_delete_compute_state; 1156 ilo->base.set_compute_resources = ilo_set_compute_resources; 1157 ilo->base.set_global_binding = ilo_set_global_binding; 1158} 1159 1160void 1161ilo_init_states(struct ilo_context *ilo) 1162{ 1163 ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor); 1164 1165 ilo_gpe_init_zs_surface(ilo->dev, NULL, 1166 PIPE_FORMAT_NONE, 0, 0, 1, &ilo->fb.null_zs); 1167 1168 ilo->dirty = ILO_DIRTY_ALL; 1169} 1170 1171void 1172ilo_cleanup_states(struct ilo_context *ilo) 1173{ 1174 unsigned i, sh; 1175 1176 for (i = 0; i < Elements(ilo->vb.states); i++) { 1177 if (ilo->vb.enabled_mask & (1 << i)) 1178 pipe_resource_reference(&ilo->vb.states[i].buffer, NULL); 1179 } 1180 1181 pipe_resource_reference(&ilo->ib.state.buffer, NULL); 1182 1183 for (i = 0; i < ilo->so.count; i++) 1184 pipe_so_target_reference(&ilo->so.states[i], NULL); 1185 1186 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 1187 for (i = 0; i < ilo->view[sh].count; i++) { 1188 struct pipe_sampler_view *view = ilo->view[sh].states[i]; 1189 pipe_sampler_view_reference(&view, NULL); 1190 } 1191 1192 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { 1193 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; 1194 pipe_resource_reference(&cbuf->resource, NULL); 1195 } 1196 } 1197 1198 for (i = 0; i < ilo->resource.count; i++) 1199 pipe_surface_reference(&ilo->resource.states[i], NULL); 1200 1201 for (i = 0; i < ilo->fb.state.nr_cbufs; i++) 1202 pipe_surface_reference(&ilo->fb.state.cbufs[i], NULL); 1203 1204 if (ilo->fb.state.zsbuf) 1205 pipe_surface_reference(&ilo->fb.state.zsbuf, NULL); 1206 1207 for (i = 0; i < ilo->cs_resource.count; i++) 1208 pipe_surface_reference(&ilo->cs_resource.states[i], NULL); 1209 1210 for (i = 0; i < ilo->global_binding.count; i++) 1211 pipe_resource_reference(&ilo->global_binding.resources[i], NULL); 1212} 1213 1214/** 1215 * Mark all states that have the resource dirty. 1216 */ 1217void 1218ilo_mark_states_with_resource_dirty(struct ilo_context *ilo, 1219 const struct pipe_resource *res) 1220{ 1221 uint32_t states = 0; 1222 unsigned sh, i; 1223 1224 if (res->target == PIPE_BUFFER) { 1225 uint32_t vb_mask = ilo->vb.enabled_mask; 1226 1227 while (vb_mask) { 1228 const unsigned idx = u_bit_scan(&vb_mask); 1229 1230 if (ilo->vb.states[idx].buffer == res) { 1231 states |= ILO_DIRTY_VERTEX_BUFFERS; 1232 break; 1233 } 1234 } 1235 1236 if (ilo->ib.state.buffer == res) 1237 states |= ILO_DIRTY_INDEX_BUFFER; 1238 1239 for (i = 0; i < ilo->so.count; i++) { 1240 if (ilo->so.states[i]->buffer == res) { 1241 states |= ILO_DIRTY_STREAM_OUTPUT_TARGETS; 1242 break; 1243 } 1244 } 1245 } 1246 1247 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 1248 for (i = 0; i < ilo->view[sh].count; i++) { 1249 struct pipe_sampler_view *view = ilo->view[sh].states[i]; 1250 1251 if (view->texture == res) { 1252 static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = { 1253 [PIPE_SHADER_VERTEX] = ILO_DIRTY_VERTEX_SAMPLER_VIEWS, 1254 [PIPE_SHADER_FRAGMENT] = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS, 1255 [PIPE_SHADER_GEOMETRY] = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS, 1256 [PIPE_SHADER_COMPUTE] = ILO_DIRTY_COMPUTE_SAMPLER_VIEWS, 1257 }; 1258 1259 states |= view_dirty_bits[sh]; 1260 break; 1261 } 1262 } 1263 1264 if (res->target == PIPE_BUFFER) { 1265 for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { 1266 struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; 1267 1268 if (cbuf->resource == res) { 1269 states |= ILO_DIRTY_CONSTANT_BUFFER; 1270 break; 1271 } 1272 } 1273 } 1274 } 1275 1276 for (i = 0; i < ilo->resource.count; i++) { 1277 if (ilo->resource.states[i]->texture == res) { 1278 states |= ILO_DIRTY_SHADER_RESOURCES; 1279 break; 1280 } 1281 } 1282 1283 /* for now? */ 1284 if (res->target != PIPE_BUFFER) { 1285 for (i = 0; i < ilo->fb.state.nr_cbufs; i++) { 1286 if (ilo->fb.state.cbufs[i]->texture == res) { 1287 states |= ILO_DIRTY_FRAMEBUFFER; 1288 break; 1289 } 1290 } 1291 1292 if (ilo->fb.state.zsbuf && ilo->fb.state.zsbuf->texture == res) 1293 states |= ILO_DIRTY_FRAMEBUFFER; 1294 } 1295 1296 for (i = 0; i < ilo->cs_resource.count; i++) { 1297 pipe_surface_reference(&ilo->cs_resource.states[i], NULL); 1298 if (ilo->cs_resource.states[i]->texture == res) { 1299 states |= ILO_DIRTY_COMPUTE_RESOURCES; 1300 break; 1301 } 1302 } 1303 1304 for (i = 0; i < ilo->global_binding.count; i++) { 1305 if (ilo->global_binding.resources[i] == res) { 1306 states |= ILO_DIRTY_GLOBAL_BINDING; 1307 break; 1308 } 1309 } 1310 1311 ilo->dirty |= states; 1312} 1313