ilo_state.c revision 6b14b392d04d8f1b43d565f65cdbd738b9f950a7
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 "ilo_context.h" 32#include "ilo_shader.h" 33#include "ilo_state.h" 34 35/* 36 * We simply remember the pipe states here and derive HW commands/states from 37 * them later. We could do better by deriving (some of the) HW 38 * commands/states directly. 39 */ 40 41static void 42finalize_shader_states(struct ilo_context *ilo) 43{ 44 /* this table is ugly and is a burden to maintain.. */ 45 const struct { 46 struct ilo_shader_state *state; 47 struct ilo_shader *prev_shader; 48 uint32_t prev_cache_seqno; 49 uint32_t dirty; 50 uint32_t deps; 51 } sh[PIPE_SHADER_TYPES] = { 52 [PIPE_SHADER_VERTEX] = { 53 .state = ilo->vs, 54 .prev_shader = (ilo->vs) ? ilo->vs->shader : NULL, 55 .prev_cache_seqno = (ilo->vs) ? ilo->vs->shader->cache_seqno : 0, 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 .prev_cache_seqno = (ilo->fs) ? ilo->fs->shader->cache_seqno : 0, 64 .dirty = ILO_DIRTY_FS, 65 .deps = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS | 66 ILO_DIRTY_RASTERIZER | 67 ILO_DIRTY_FRAMEBUFFER, 68 }, 69 [PIPE_SHADER_GEOMETRY] = { 70 .state = ilo->gs, 71 .prev_shader = (ilo->gs) ? ilo->gs->shader : NULL, 72 .prev_cache_seqno = (ilo->gs) ? ilo->gs->shader->cache_seqno : 0, 73 .dirty = ILO_DIRTY_GS, 74 .deps = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS | 75 ILO_DIRTY_VS | 76 ILO_DIRTY_RASTERIZER, 77 }, 78 [PIPE_SHADER_COMPUTE] = { 79 .state = NULL, 80 .prev_shader = NULL, 81 .prev_cache_seqno = 0, 82 .dirty = 0, 83 .deps = 0, 84 }, 85 }; 86 struct ilo_shader *shaders[PIPE_SHADER_TYPES]; 87 int num_shaders = 0, i; 88 89 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 90 /* no state bound */ 91 if (!sh[i].state) 92 continue; 93 94 /* switch variant if the shader or the states it depends on changed */ 95 if (ilo->dirty & (sh[i].dirty | sh[i].deps)) { 96 struct ilo_shader_variant variant; 97 98 ilo_shader_variant_init(&variant, &sh[i].state->info, ilo); 99 ilo_shader_state_use_variant(sh[i].state, &variant); 100 } 101 102 shaders[num_shaders++] = sh[i].state->shader; 103 } 104 105 ilo_shader_cache_set(ilo->shader_cache, shaders, num_shaders); 106 107 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 108 /* no state bound */ 109 if (!sh[i].state) 110 continue; 111 112 /* 113 * mark the shader state dirty if 114 * 115 * - a new variant is selected, or 116 * - the kernel is uploaded to a different bo 117 */ 118 if (sh[i].state->shader != sh[i].prev_shader || 119 sh[i].state->shader->cache_seqno != sh[i].prev_cache_seqno) 120 ilo->dirty |= sh[i].dirty; 121 } 122} 123 124static void 125finalize_constant_buffers(struct ilo_context *ilo) 126{ 127 int sh; 128 129 if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER)) 130 return; 131 132 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 133 int last_cbuf = Elements(ilo->constant_buffers[sh].buffers) - 1; 134 135 /* find the last cbuf */ 136 while (last_cbuf >= 0 && 137 !ilo->constant_buffers[sh].buffers[last_cbuf].buffer) 138 last_cbuf--; 139 140 ilo->constant_buffers[sh].num_buffers = last_cbuf + 1; 141 } 142} 143 144/** 145 * Finalize states. Some states depend on other states and are 146 * incomplete/invalid until finalized. 147 */ 148void 149ilo_finalize_states(struct ilo_context *ilo) 150{ 151 finalize_shader_states(ilo); 152 finalize_constant_buffers(ilo); 153} 154 155static void * 156ilo_create_blend_state(struct pipe_context *pipe, 157 const struct pipe_blend_state *state) 158{ 159 struct pipe_blend_state *blend; 160 161 blend = MALLOC_STRUCT(pipe_blend_state); 162 assert(blend); 163 164 *blend = *state; 165 166 return blend; 167} 168 169static void 170ilo_bind_blend_state(struct pipe_context *pipe, void *state) 171{ 172 struct ilo_context *ilo = ilo_context(pipe); 173 174 ilo->blend = state; 175 176 ilo->dirty |= ILO_DIRTY_BLEND; 177} 178 179static void 180ilo_delete_blend_state(struct pipe_context *pipe, void *state) 181{ 182 FREE(state); 183} 184 185static void * 186ilo_create_sampler_state(struct pipe_context *pipe, 187 const struct pipe_sampler_state *state) 188{ 189 struct pipe_sampler_state *sampler; 190 191 sampler = MALLOC_STRUCT(pipe_sampler_state); 192 assert(sampler); 193 194 *sampler = *state; 195 196 return sampler; 197} 198 199static void 200bind_samplers(struct ilo_context *ilo, 201 unsigned shader, unsigned start, unsigned count, 202 void **samplers, bool unbind_old) 203{ 204 struct pipe_sampler_state **dst = ilo->samplers[shader].samplers; 205 unsigned i; 206 207 assert(start + count <= Elements(ilo->samplers[shader].samplers)); 208 209 if (unbind_old) { 210 if (!samplers) { 211 start = 0; 212 count = 0; 213 } 214 215 for (i = 0; i < start; i++) 216 dst[i] = NULL; 217 for (; i < start + count; i++) 218 dst[i] = samplers[i - start]; 219 for (; i < ilo->samplers[shader].num_samplers; i++) 220 dst[i] = NULL; 221 222 ilo->samplers[shader].num_samplers = start + count; 223 224 return; 225 } 226 227 dst += start; 228 if (samplers) { 229 for (i = 0; i < count; i++) 230 dst[i] = samplers[i]; 231 } 232 else { 233 for (i = 0; i < count; i++) 234 dst[i] = NULL; 235 } 236 237 if (ilo->samplers[shader].num_samplers <= start + count) { 238 count += start; 239 240 while (count > 0 && !ilo->samplers[shader].samplers[count - 1]) 241 count--; 242 243 ilo->samplers[shader].num_samplers = count; 244 } 245} 246 247static void 248ilo_bind_fragment_sampler_states(struct pipe_context *pipe, 249 unsigned num_samplers, 250 void **samplers) 251{ 252 struct ilo_context *ilo = ilo_context(pipe); 253 254 bind_samplers(ilo, PIPE_SHADER_FRAGMENT, 0, num_samplers, samplers, true); 255 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLERS; 256} 257 258static void 259ilo_bind_vertex_sampler_states(struct pipe_context *pipe, 260 unsigned num_samplers, 261 void **samplers) 262{ 263 struct ilo_context *ilo = ilo_context(pipe); 264 265 bind_samplers(ilo, PIPE_SHADER_VERTEX, 0, num_samplers, samplers, true); 266 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLERS; 267} 268 269static void 270ilo_bind_geometry_sampler_states(struct pipe_context *pipe, 271 unsigned num_samplers, 272 void **samplers) 273{ 274 struct ilo_context *ilo = ilo_context(pipe); 275 276 bind_samplers(ilo, PIPE_SHADER_GEOMETRY, 0, num_samplers, samplers, true); 277 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLERS; 278} 279 280static void 281ilo_bind_compute_sampler_states(struct pipe_context *pipe, 282 unsigned start_slot, 283 unsigned num_samplers, 284 void **samplers) 285{ 286 struct ilo_context *ilo = ilo_context(pipe); 287 288 bind_samplers(ilo, PIPE_SHADER_COMPUTE, 289 start_slot, num_samplers, samplers, false); 290 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLERS; 291} 292 293static void 294ilo_delete_sampler_state(struct pipe_context *pipe, void *state) 295{ 296 FREE(state); 297} 298 299static void * 300ilo_create_rasterizer_state(struct pipe_context *pipe, 301 const struct pipe_rasterizer_state *state) 302{ 303 struct pipe_rasterizer_state *rast; 304 305 rast = MALLOC_STRUCT(pipe_rasterizer_state); 306 assert(rast); 307 308 *rast = *state; 309 310 return rast; 311} 312 313static void 314ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state) 315{ 316 struct ilo_context *ilo = ilo_context(pipe); 317 318 ilo->rasterizer = state; 319 320 ilo->dirty |= ILO_DIRTY_RASTERIZER; 321} 322 323static void 324ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state) 325{ 326 FREE(state); 327} 328 329static void * 330ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe, 331 const struct pipe_depth_stencil_alpha_state *state) 332{ 333 struct pipe_depth_stencil_alpha_state *dsa; 334 335 dsa = MALLOC_STRUCT(pipe_depth_stencil_alpha_state); 336 assert(dsa); 337 338 *dsa = *state; 339 340 return dsa; 341} 342 343static void 344ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 345{ 346 struct ilo_context *ilo = ilo_context(pipe); 347 348 ilo->depth_stencil_alpha = state; 349 350 ilo->dirty |= ILO_DIRTY_DEPTH_STENCIL_ALPHA; 351} 352 353static void 354ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) 355{ 356 FREE(state); 357} 358 359static void * 360ilo_create_fs_state(struct pipe_context *pipe, 361 const struct pipe_shader_state *state) 362{ 363 struct ilo_context *ilo = ilo_context(pipe); 364 return ilo_shader_state_create(ilo, PIPE_SHADER_FRAGMENT, state); 365} 366 367static void 368ilo_bind_fs_state(struct pipe_context *pipe, void *state) 369{ 370 struct ilo_context *ilo = ilo_context(pipe); 371 372 ilo->fs = state; 373 374 ilo->dirty |= ILO_DIRTY_FS; 375} 376 377static void 378ilo_delete_fs_state(struct pipe_context *pipe, void *state) 379{ 380 struct ilo_shader_state *fs = (struct ilo_shader_state *) state; 381 ilo_shader_state_destroy(fs); 382} 383 384static void * 385ilo_create_vs_state(struct pipe_context *pipe, 386 const struct pipe_shader_state *state) 387{ 388 struct ilo_context *ilo = ilo_context(pipe); 389 return ilo_shader_state_create(ilo, PIPE_SHADER_VERTEX, state); 390} 391 392static void 393ilo_bind_vs_state(struct pipe_context *pipe, void *state) 394{ 395 struct ilo_context *ilo = ilo_context(pipe); 396 397 ilo->vs = state; 398 399 ilo->dirty |= ILO_DIRTY_VS; 400} 401 402static void 403ilo_delete_vs_state(struct pipe_context *pipe, void *state) 404{ 405 struct ilo_shader_state *vs = (struct ilo_shader_state *) state; 406 ilo_shader_state_destroy(vs); 407} 408 409static void * 410ilo_create_gs_state(struct pipe_context *pipe, 411 const struct pipe_shader_state *state) 412{ 413 struct ilo_context *ilo = ilo_context(pipe); 414 return ilo_shader_state_create(ilo, PIPE_SHADER_GEOMETRY, state); 415} 416 417static void 418ilo_bind_gs_state(struct pipe_context *pipe, void *state) 419{ 420 struct ilo_context *ilo = ilo_context(pipe); 421 422 ilo->gs = state; 423 424 ilo->dirty |= ILO_DIRTY_GS; 425} 426 427static void 428ilo_delete_gs_state(struct pipe_context *pipe, void *state) 429{ 430 struct ilo_shader_state *gs = (struct ilo_shader_state *) state; 431 ilo_shader_state_destroy(gs); 432} 433 434static void * 435ilo_create_vertex_elements_state(struct pipe_context *pipe, 436 unsigned num_elements, 437 const struct pipe_vertex_element *elements) 438{ 439 struct ilo_ve_state *ve; 440 441 ve = MALLOC_STRUCT(ilo_ve_state); 442 assert(ve); 443 444 memcpy(ve->states, elements, sizeof(*elements) * num_elements); 445 ve->count = num_elements; 446 447 return ve; 448} 449 450static void 451ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state) 452{ 453 struct ilo_context *ilo = ilo_context(pipe); 454 455 ilo->ve = state; 456 457 ilo->dirty |= ILO_DIRTY_VERTEX_ELEMENTS; 458} 459 460static void 461ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state) 462{ 463 struct ilo_ve_state *ve = state; 464 465 FREE(ve); 466} 467 468static void 469ilo_set_blend_color(struct pipe_context *pipe, 470 const struct pipe_blend_color *state) 471{ 472 struct ilo_context *ilo = ilo_context(pipe); 473 474 ilo->blend_color = *state; 475 476 ilo->dirty |= ILO_DIRTY_BLEND_COLOR; 477} 478 479static void 480ilo_set_stencil_ref(struct pipe_context *pipe, 481 const struct pipe_stencil_ref *state) 482{ 483 struct ilo_context *ilo = ilo_context(pipe); 484 485 ilo->stencil_ref = *state; 486 487 ilo->dirty |= ILO_DIRTY_STENCIL_REF; 488} 489 490static void 491ilo_set_sample_mask(struct pipe_context *pipe, 492 unsigned sample_mask) 493{ 494 struct ilo_context *ilo = ilo_context(pipe); 495 496 ilo->sample_mask = sample_mask; 497 498 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK; 499} 500 501static void 502ilo_set_clip_state(struct pipe_context *pipe, 503 const struct pipe_clip_state *state) 504{ 505 struct ilo_context *ilo = ilo_context(pipe); 506 507 ilo->clip = *state; 508 509 ilo->dirty |= ILO_DIRTY_CLIP; 510} 511 512static void 513ilo_set_constant_buffer(struct pipe_context *pipe, 514 uint shader, uint index, 515 struct pipe_constant_buffer *buf) 516{ 517 struct ilo_context *ilo = ilo_context(pipe); 518 struct pipe_constant_buffer *cbuf; 519 520 assert(shader < Elements(ilo->constant_buffers)); 521 assert(index < Elements(ilo->constant_buffers[shader].buffers)); 522 523 cbuf = &ilo->constant_buffers[shader].buffers[index]; 524 525 pipe_resource_reference(&cbuf->buffer, NULL); 526 527 if (buf) { 528 pipe_resource_reference(&cbuf->buffer, buf->buffer); 529 cbuf->buffer_offset = buf->buffer_offset; 530 cbuf->buffer_size = buf->buffer_size; 531 cbuf->user_buffer = buf->user_buffer; 532 } 533 else { 534 cbuf->buffer_offset = 0; 535 cbuf->buffer_size = 0; 536 cbuf->user_buffer = 0; 537 } 538 539 /* the correct value will be set in ilo_finalize_states() */ 540 ilo->constant_buffers[shader].num_buffers = 0; 541 542 ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER; 543} 544 545static void 546ilo_set_framebuffer_state(struct pipe_context *pipe, 547 const struct pipe_framebuffer_state *state) 548{ 549 struct ilo_context *ilo = ilo_context(pipe); 550 551 util_copy_framebuffer_state(&ilo->framebuffer, state); 552 553 ilo->dirty |= ILO_DIRTY_FRAMEBUFFER; 554} 555 556static void 557ilo_set_polygon_stipple(struct pipe_context *pipe, 558 const struct pipe_poly_stipple *state) 559{ 560 struct ilo_context *ilo = ilo_context(pipe); 561 562 ilo->poly_stipple = *state; 563 564 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE; 565} 566 567static void 568ilo_set_scissor_states(struct pipe_context *pipe, 569 unsigned start_slot, 570 unsigned num_scissors, 571 const struct pipe_scissor_state *state) 572{ 573 struct ilo_context *ilo = ilo_context(pipe); 574 575 ilo->scissor = *state; 576 577 ilo->dirty |= ILO_DIRTY_SCISSOR; 578} 579 580static void 581ilo_set_viewport_states(struct pipe_context *pipe, 582 unsigned start_slot, 583 unsigned num_viewports, 584 const struct pipe_viewport_state *state) 585{ 586 struct ilo_context *ilo = ilo_context(pipe); 587 588 ilo->viewport = *state; 589 590 ilo->dirty |= ILO_DIRTY_VIEWPORT; 591} 592 593static void 594set_sampler_views(struct ilo_context *ilo, 595 unsigned shader, unsigned start, unsigned count, 596 struct pipe_sampler_view **views, bool unset_old) 597{ 598 struct pipe_sampler_view **dst = ilo->sampler_views[shader].views; 599 unsigned i; 600 601 assert(start + count <= Elements(ilo->sampler_views[shader].views)); 602 603 if (unset_old) { 604 if (!views) { 605 start = 0; 606 count = 0; 607 } 608 609 for (i = 0; i < start; i++) 610 pipe_sampler_view_reference(&dst[i], NULL); 611 for (; i < start + count; i++) 612 pipe_sampler_view_reference(&dst[i], views[i - start]); 613 for (; i < ilo->sampler_views[shader].num_views; i++) 614 pipe_sampler_view_reference(&dst[i], NULL); 615 616 ilo->sampler_views[shader].num_views = start + count; 617 618 return; 619 } 620 621 dst += start; 622 if (views) { 623 for (i = 0; i < count; i++) 624 pipe_sampler_view_reference(&dst[i], views[i]); 625 } 626 else { 627 for (i = 0; i < count; i++) 628 pipe_sampler_view_reference(&dst[i], NULL); 629 } 630 631 if (ilo->sampler_views[shader].num_views <= start + count) { 632 count += start; 633 634 while (count > 0 && !ilo->sampler_views[shader].views[count - 1]) 635 count--; 636 637 ilo->sampler_views[shader].num_views = count; 638 } 639} 640 641static void 642ilo_set_fragment_sampler_views(struct pipe_context *pipe, 643 unsigned num_views, 644 struct pipe_sampler_view **views) 645{ 646 struct ilo_context *ilo = ilo_context(pipe); 647 648 set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true); 649 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS; 650} 651 652static void 653ilo_set_vertex_sampler_views(struct pipe_context *pipe, 654 unsigned num_views, 655 struct pipe_sampler_view **views) 656{ 657 struct ilo_context *ilo = ilo_context(pipe); 658 659 set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true); 660 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS; 661} 662 663static void 664ilo_set_geometry_sampler_views(struct pipe_context *pipe, 665 unsigned num_views, 666 struct pipe_sampler_view **views) 667{ 668 struct ilo_context *ilo = ilo_context(pipe); 669 670 set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true); 671 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS; 672} 673 674static void 675ilo_set_compute_sampler_views(struct pipe_context *pipe, 676 unsigned start_slot, unsigned num_views, 677 struct pipe_sampler_view **views) 678{ 679 struct ilo_context *ilo = ilo_context(pipe); 680 681 set_sampler_views(ilo, PIPE_SHADER_COMPUTE, 682 start_slot, num_views, views, false); 683 684 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS; 685} 686 687static void 688ilo_set_shader_resources(struct pipe_context *pipe, 689 unsigned start, unsigned count, 690 struct pipe_surface **surfaces) 691{ 692 struct ilo_context *ilo = ilo_context(pipe); 693 struct pipe_surface **dst = ilo->shader_resources.surfaces; 694 unsigned i; 695 696 assert(start + count <= Elements(ilo->shader_resources.surfaces)); 697 698 dst += start; 699 if (surfaces) { 700 for (i = 0; i < count; i++) 701 pipe_surface_reference(&dst[i], surfaces[i]); 702 } 703 else { 704 for (i = 0; i < count; i++) 705 pipe_surface_reference(&dst[i], NULL); 706 } 707 708 if (ilo->shader_resources.num_surfaces <= start + count) { 709 count += start; 710 711 while (count > 0 && !ilo->shader_resources.surfaces[count - 1]) 712 count--; 713 714 ilo->shader_resources.num_surfaces = count; 715 } 716 717 ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES; 718} 719 720static void 721ilo_set_vertex_buffers(struct pipe_context *pipe, 722 unsigned start_slot, unsigned num_buffers, 723 const struct pipe_vertex_buffer *buffers) 724{ 725 struct ilo_context *ilo = ilo_context(pipe); 726 727 util_set_vertex_buffers_mask(ilo->vb.states, 728 &ilo->vb.enabled_mask, buffers, start_slot, num_buffers); 729 730 ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS; 731} 732 733static void 734ilo_set_index_buffer(struct pipe_context *pipe, 735 const struct pipe_index_buffer *state) 736{ 737 struct ilo_context *ilo = ilo_context(pipe); 738 739 if (state) { 740 ilo->ib.state.index_size = state->index_size; 741 ilo->ib.state.offset = state->offset; 742 pipe_resource_reference(&ilo->ib.state.buffer, state->buffer); 743 ilo->ib.state.user_buffer = state->user_buffer; 744 } 745 else { 746 ilo->ib.state.index_size = 0; 747 ilo->ib.state.offset = 0; 748 pipe_resource_reference(&ilo->ib.state.buffer, NULL); 749 ilo->ib.state.user_buffer = NULL; 750 } 751 752 ilo->dirty |= ILO_DIRTY_INDEX_BUFFER; 753} 754 755static struct pipe_stream_output_target * 756ilo_create_stream_output_target(struct pipe_context *pipe, 757 struct pipe_resource *res, 758 unsigned buffer_offset, 759 unsigned buffer_size) 760{ 761 struct pipe_stream_output_target *target; 762 763 target = MALLOC_STRUCT(pipe_stream_output_target); 764 assert(target); 765 766 pipe_reference_init(&target->reference, 1); 767 target->buffer = NULL; 768 pipe_resource_reference(&target->buffer, res); 769 target->context = pipe; 770 target->buffer_offset = buffer_offset; 771 target->buffer_size = buffer_size; 772 773 return target; 774} 775 776static void 777ilo_set_stream_output_targets(struct pipe_context *pipe, 778 unsigned num_targets, 779 struct pipe_stream_output_target **targets, 780 unsigned append_bitmask) 781{ 782 struct ilo_context *ilo = ilo_context(pipe); 783 unsigned i; 784 785 if (!targets) 786 num_targets = 0; 787 788 for (i = 0; i < num_targets; i++) { 789 pipe_so_target_reference(&ilo->stream_output_targets.targets[i], 790 targets[i]); 791 } 792 for (; i < ilo->stream_output_targets.num_targets; i++) 793 pipe_so_target_reference(&ilo->stream_output_targets.targets[i], NULL); 794 795 ilo->stream_output_targets.num_targets = num_targets; 796 ilo->stream_output_targets.append_bitmask = append_bitmask; 797 798 ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS; 799} 800 801static void 802ilo_stream_output_target_destroy(struct pipe_context *pipe, 803 struct pipe_stream_output_target *target) 804{ 805 pipe_resource_reference(&target->buffer, NULL); 806 FREE(target); 807} 808 809static struct pipe_sampler_view * 810ilo_create_sampler_view(struct pipe_context *pipe, 811 struct pipe_resource *res, 812 const struct pipe_sampler_view *templ) 813{ 814 struct pipe_sampler_view *view; 815 816 view = MALLOC_STRUCT(pipe_sampler_view); 817 assert(view); 818 819 *view = *templ; 820 pipe_reference_init(&view->reference, 1); 821 view->texture = NULL; 822 pipe_resource_reference(&view->texture, res); 823 view->context = pipe; 824 825 return view; 826} 827 828static void 829ilo_sampler_view_destroy(struct pipe_context *pipe, 830 struct pipe_sampler_view *view) 831{ 832 pipe_resource_reference(&view->texture, NULL); 833 FREE(view); 834} 835 836static struct pipe_surface * 837ilo_create_surface(struct pipe_context *pipe, 838 struct pipe_resource *res, 839 const struct pipe_surface *templ) 840{ 841 struct pipe_surface *surface; 842 843 surface = MALLOC_STRUCT(pipe_surface); 844 assert(surface); 845 846 *surface = *templ; 847 pipe_reference_init(&surface->reference, 1); 848 surface->texture = NULL; 849 pipe_resource_reference(&surface->texture, res); 850 851 surface->context = pipe; 852 surface->width = u_minify(res->width0, surface->u.tex.level); 853 surface->height = u_minify(res->height0, surface->u.tex.level); 854 855 return surface; 856} 857 858static void 859ilo_surface_destroy(struct pipe_context *pipe, 860 struct pipe_surface *surface) 861{ 862 pipe_resource_reference(&surface->texture, NULL); 863 FREE(surface); 864} 865 866static void * 867ilo_create_compute_state(struct pipe_context *pipe, 868 const struct pipe_compute_state *state) 869{ 870 struct ilo_context *ilo = ilo_context(pipe); 871 return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state); 872} 873 874static void 875ilo_bind_compute_state(struct pipe_context *pipe, void *state) 876{ 877 struct ilo_context *ilo = ilo_context(pipe); 878 879 ilo->compute = state; 880 881 ilo->dirty |= ILO_DIRTY_COMPUTE; 882} 883 884static void 885ilo_delete_compute_state(struct pipe_context *pipe, void *state) 886{ 887 struct ilo_shader_state *cs = (struct ilo_shader_state *) state; 888 ilo_shader_state_destroy(cs); 889} 890 891static void 892ilo_set_compute_resources(struct pipe_context *pipe, 893 unsigned start, unsigned count, 894 struct pipe_surface **surfaces) 895{ 896 struct ilo_context *ilo = ilo_context(pipe); 897 struct pipe_surface **dst = ilo->compute_resources.surfaces; 898 unsigned i; 899 900 assert(start + count <= Elements(ilo->compute_resources.surfaces)); 901 902 dst += start; 903 if (surfaces) { 904 for (i = 0; i < count; i++) 905 pipe_surface_reference(&dst[i], surfaces[i]); 906 } 907 else { 908 for (i = 0; i < count; i++) 909 pipe_surface_reference(&dst[i], NULL); 910 } 911 912 if (ilo->compute_resources.num_surfaces <= start + count) { 913 count += start; 914 915 while (count > 0 && !ilo->compute_resources.surfaces[count - 1]) 916 count--; 917 918 ilo->compute_resources.num_surfaces = count; 919 } 920 921 ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES; 922} 923 924static void 925ilo_set_global_binding(struct pipe_context *pipe, 926 unsigned start, unsigned count, 927 struct pipe_resource **resources, 928 uint32_t **handles) 929{ 930 struct ilo_context *ilo = ilo_context(pipe); 931 struct pipe_resource **dst = ilo->global_binding.resources; 932 unsigned i; 933 934 assert(start + count <= Elements(ilo->global_binding.resources)); 935 936 dst += start; 937 if (resources) { 938 for (i = 0; i < count; i++) 939 pipe_resource_reference(&dst[i], resources[i]); 940 } 941 else { 942 for (i = 0; i < count; i++) 943 pipe_resource_reference(&dst[i], NULL); 944 } 945 946 if (ilo->global_binding.num_resources <= start + count) { 947 count += start; 948 949 while (count > 0 && !ilo->global_binding.resources[count - 1]) 950 count--; 951 952 ilo->global_binding.num_resources = count; 953 } 954 955 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING; 956} 957 958/** 959 * Initialize state-related functions. 960 */ 961void 962ilo_init_state_functions(struct ilo_context *ilo) 963{ 964 STATIC_ASSERT(ILO_STATE_COUNT <= 32); 965 966 ilo->base.create_blend_state = ilo_create_blend_state; 967 ilo->base.bind_blend_state = ilo_bind_blend_state; 968 ilo->base.delete_blend_state = ilo_delete_blend_state; 969 ilo->base.create_sampler_state = ilo_create_sampler_state; 970 ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states; 971 ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states; 972 ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states; 973 ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states; 974 ilo->base.delete_sampler_state = ilo_delete_sampler_state; 975 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state; 976 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state; 977 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state; 978 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state; 979 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state; 980 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state; 981 ilo->base.create_fs_state = ilo_create_fs_state; 982 ilo->base.bind_fs_state = ilo_bind_fs_state; 983 ilo->base.delete_fs_state = ilo_delete_fs_state; 984 ilo->base.create_vs_state = ilo_create_vs_state; 985 ilo->base.bind_vs_state = ilo_bind_vs_state; 986 ilo->base.delete_vs_state = ilo_delete_vs_state; 987 ilo->base.create_gs_state = ilo_create_gs_state; 988 ilo->base.bind_gs_state = ilo_bind_gs_state; 989 ilo->base.delete_gs_state = ilo_delete_gs_state; 990 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state; 991 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state; 992 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state; 993 994 ilo->base.set_blend_color = ilo_set_blend_color; 995 ilo->base.set_stencil_ref = ilo_set_stencil_ref; 996 ilo->base.set_sample_mask = ilo_set_sample_mask; 997 ilo->base.set_clip_state = ilo_set_clip_state; 998 ilo->base.set_constant_buffer = ilo_set_constant_buffer; 999 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state; 1000 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple; 1001 ilo->base.set_scissor_states = ilo_set_scissor_states; 1002 ilo->base.set_viewport_states = ilo_set_viewport_states; 1003 ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views; 1004 ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views; 1005 ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views; 1006 ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views; 1007 ilo->base.set_shader_resources = ilo_set_shader_resources; 1008 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers; 1009 ilo->base.set_index_buffer = ilo_set_index_buffer; 1010 1011 ilo->base.create_stream_output_target = ilo_create_stream_output_target; 1012 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy; 1013 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets; 1014 1015 ilo->base.create_sampler_view = ilo_create_sampler_view; 1016 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy; 1017 1018 ilo->base.create_surface = ilo_create_surface; 1019 ilo->base.surface_destroy = ilo_surface_destroy; 1020 1021 ilo->base.create_compute_state = ilo_create_compute_state; 1022 ilo->base.bind_compute_state = ilo_bind_compute_state; 1023 ilo->base.delete_compute_state = ilo_delete_compute_state; 1024 ilo->base.set_compute_resources = ilo_set_compute_resources; 1025 ilo->base.set_global_binding = ilo_set_global_binding; 1026} 1027