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