ilo_state.c revision eaabb4ead07ae043ecc789024028e225ebd0f318
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_vertex_element *velem; 440 441 velem = MALLOC_STRUCT(ilo_vertex_element); 442 assert(velem); 443 444 memcpy(velem->elements, elements, sizeof(*elements) * num_elements); 445 velem->num_elements = num_elements; 446 447 return velem; 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->vertex_elements = 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 FREE(state); 464} 465 466static void 467ilo_set_blend_color(struct pipe_context *pipe, 468 const struct pipe_blend_color *state) 469{ 470 struct ilo_context *ilo = ilo_context(pipe); 471 472 ilo->blend_color = *state; 473 474 ilo->dirty |= ILO_DIRTY_BLEND_COLOR; 475} 476 477static void 478ilo_set_stencil_ref(struct pipe_context *pipe, 479 const struct pipe_stencil_ref *state) 480{ 481 struct ilo_context *ilo = ilo_context(pipe); 482 483 ilo->stencil_ref = *state; 484 485 ilo->dirty |= ILO_DIRTY_STENCIL_REF; 486} 487 488static void 489ilo_set_sample_mask(struct pipe_context *pipe, 490 unsigned sample_mask) 491{ 492 struct ilo_context *ilo = ilo_context(pipe); 493 494 ilo->sample_mask = sample_mask; 495 496 ilo->dirty |= ILO_DIRTY_SAMPLE_MASK; 497} 498 499static void 500ilo_set_clip_state(struct pipe_context *pipe, 501 const struct pipe_clip_state *state) 502{ 503 struct ilo_context *ilo = ilo_context(pipe); 504 505 ilo->clip = *state; 506 507 ilo->dirty |= ILO_DIRTY_CLIP; 508} 509 510static void 511ilo_set_constant_buffer(struct pipe_context *pipe, 512 uint shader, uint index, 513 struct pipe_constant_buffer *buf) 514{ 515 struct ilo_context *ilo = ilo_context(pipe); 516 struct pipe_constant_buffer *cbuf; 517 518 assert(shader < Elements(ilo->constant_buffers)); 519 assert(index < Elements(ilo->constant_buffers[shader].buffers)); 520 521 cbuf = &ilo->constant_buffers[shader].buffers[index]; 522 523 pipe_resource_reference(&cbuf->buffer, NULL); 524 525 if (buf) { 526 pipe_resource_reference(&cbuf->buffer, buf->buffer); 527 cbuf->buffer_offset = buf->buffer_offset; 528 cbuf->buffer_size = buf->buffer_size; 529 cbuf->user_buffer = buf->user_buffer; 530 } 531 else { 532 cbuf->buffer_offset = 0; 533 cbuf->buffer_size = 0; 534 cbuf->user_buffer = 0; 535 } 536 537 /* the correct value will be set in ilo_finalize_states() */ 538 ilo->constant_buffers[shader].num_buffers = 0; 539 540 ilo->dirty |= ILO_DIRTY_CONSTANT_BUFFER; 541} 542 543static void 544ilo_set_framebuffer_state(struct pipe_context *pipe, 545 const struct pipe_framebuffer_state *state) 546{ 547 struct ilo_context *ilo = ilo_context(pipe); 548 549 util_copy_framebuffer_state(&ilo->framebuffer, state); 550 551 ilo->dirty |= ILO_DIRTY_FRAMEBUFFER; 552} 553 554static void 555ilo_set_polygon_stipple(struct pipe_context *pipe, 556 const struct pipe_poly_stipple *state) 557{ 558 struct ilo_context *ilo = ilo_context(pipe); 559 560 ilo->poly_stipple = *state; 561 562 ilo->dirty |= ILO_DIRTY_POLY_STIPPLE; 563} 564 565static void 566ilo_set_scissor_states(struct pipe_context *pipe, 567 unsigned start_slot, 568 unsigned num_scissors, 569 const struct pipe_scissor_state *state) 570{ 571 struct ilo_context *ilo = ilo_context(pipe); 572 573 ilo->scissor = *state; 574 575 ilo->dirty |= ILO_DIRTY_SCISSOR; 576} 577 578static void 579ilo_set_viewport_states(struct pipe_context *pipe, 580 unsigned start_slot, 581 unsigned num_viewports, 582 const struct pipe_viewport_state *state) 583{ 584 struct ilo_context *ilo = ilo_context(pipe); 585 586 ilo->viewport = *state; 587 588 ilo->dirty |= ILO_DIRTY_VIEWPORT; 589} 590 591static void 592set_sampler_views(struct ilo_context *ilo, 593 unsigned shader, unsigned start, unsigned count, 594 struct pipe_sampler_view **views, bool unset_old) 595{ 596 struct pipe_sampler_view **dst = ilo->sampler_views[shader].views; 597 unsigned i; 598 599 assert(start + count <= Elements(ilo->sampler_views[shader].views)); 600 601 if (unset_old) { 602 if (!views) { 603 start = 0; 604 count = 0; 605 } 606 607 for (i = 0; i < start; i++) 608 pipe_sampler_view_reference(&dst[i], NULL); 609 for (; i < start + count; i++) 610 pipe_sampler_view_reference(&dst[i], views[i - start]); 611 for (; i < ilo->sampler_views[shader].num_views; i++) 612 pipe_sampler_view_reference(&dst[i], NULL); 613 614 ilo->sampler_views[shader].num_views = start + count; 615 616 return; 617 } 618 619 dst += start; 620 if (views) { 621 for (i = 0; i < count; i++) 622 pipe_sampler_view_reference(&dst[i], views[i]); 623 } 624 else { 625 for (i = 0; i < count; i++) 626 pipe_sampler_view_reference(&dst[i], NULL); 627 } 628 629 if (ilo->sampler_views[shader].num_views <= start + count) { 630 count += start; 631 632 while (count > 0 && !ilo->sampler_views[shader].views[count - 1]) 633 count--; 634 635 ilo->sampler_views[shader].num_views = count; 636 } 637} 638 639static void 640ilo_set_fragment_sampler_views(struct pipe_context *pipe, 641 unsigned num_views, 642 struct pipe_sampler_view **views) 643{ 644 struct ilo_context *ilo = ilo_context(pipe); 645 646 set_sampler_views(ilo, PIPE_SHADER_FRAGMENT, 0, num_views, views, true); 647 ilo->dirty |= ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS; 648} 649 650static void 651ilo_set_vertex_sampler_views(struct pipe_context *pipe, 652 unsigned num_views, 653 struct pipe_sampler_view **views) 654{ 655 struct ilo_context *ilo = ilo_context(pipe); 656 657 set_sampler_views(ilo, PIPE_SHADER_VERTEX, 0, num_views, views, true); 658 ilo->dirty |= ILO_DIRTY_VERTEX_SAMPLER_VIEWS; 659} 660 661static void 662ilo_set_geometry_sampler_views(struct pipe_context *pipe, 663 unsigned num_views, 664 struct pipe_sampler_view **views) 665{ 666 struct ilo_context *ilo = ilo_context(pipe); 667 668 set_sampler_views(ilo, PIPE_SHADER_GEOMETRY, 0, num_views, views, true); 669 ilo->dirty |= ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS; 670} 671 672static void 673ilo_set_compute_sampler_views(struct pipe_context *pipe, 674 unsigned start_slot, unsigned num_views, 675 struct pipe_sampler_view **views) 676{ 677 struct ilo_context *ilo = ilo_context(pipe); 678 679 set_sampler_views(ilo, PIPE_SHADER_COMPUTE, 680 start_slot, num_views, views, false); 681 682 ilo->dirty |= ILO_DIRTY_COMPUTE_SAMPLER_VIEWS; 683} 684 685static void 686ilo_set_shader_resources(struct pipe_context *pipe, 687 unsigned start, unsigned count, 688 struct pipe_surface **surfaces) 689{ 690 struct ilo_context *ilo = ilo_context(pipe); 691 struct pipe_surface **dst = ilo->shader_resources.surfaces; 692 unsigned i; 693 694 assert(start + count <= Elements(ilo->shader_resources.surfaces)); 695 696 dst += start; 697 if (surfaces) { 698 for (i = 0; i < count; i++) 699 pipe_surface_reference(&dst[i], surfaces[i]); 700 } 701 else { 702 for (i = 0; i < count; i++) 703 pipe_surface_reference(&dst[i], NULL); 704 } 705 706 if (ilo->shader_resources.num_surfaces <= start + count) { 707 count += start; 708 709 while (count > 0 && !ilo->shader_resources.surfaces[count - 1]) 710 count--; 711 712 ilo->shader_resources.num_surfaces = count; 713 } 714 715 ilo->dirty |= ILO_DIRTY_SHADER_RESOURCES; 716} 717 718static void 719ilo_set_vertex_buffers(struct pipe_context *pipe, 720 unsigned start_slot, unsigned num_buffers, 721 const struct pipe_vertex_buffer *buffers) 722{ 723 struct ilo_context *ilo = ilo_context(pipe); 724 725 util_set_vertex_buffers_count(ilo->vertex_buffers.buffers, 726 &ilo->vertex_buffers.num_buffers, buffers, start_slot, num_buffers); 727 728 ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS; 729} 730 731static void 732ilo_set_index_buffer(struct pipe_context *pipe, 733 const struct pipe_index_buffer *state) 734{ 735 struct ilo_context *ilo = ilo_context(pipe); 736 737 if (state) { 738 ilo->index_buffer.index_size = state->index_size; 739 ilo->index_buffer.offset = state->offset; 740 pipe_resource_reference(&ilo->index_buffer.buffer, state->buffer); 741 ilo->index_buffer.user_buffer = state->user_buffer; 742 } 743 else { 744 ilo->index_buffer.index_size = 0; 745 ilo->index_buffer.offset = 0; 746 pipe_resource_reference(&ilo->index_buffer.buffer, NULL); 747 ilo->index_buffer.user_buffer = NULL; 748 } 749 750 ilo->dirty |= ILO_DIRTY_INDEX_BUFFER; 751} 752 753static struct pipe_stream_output_target * 754ilo_create_stream_output_target(struct pipe_context *pipe, 755 struct pipe_resource *res, 756 unsigned buffer_offset, 757 unsigned buffer_size) 758{ 759 struct pipe_stream_output_target *target; 760 761 target = MALLOC_STRUCT(pipe_stream_output_target); 762 assert(target); 763 764 pipe_reference_init(&target->reference, 1); 765 target->buffer = NULL; 766 pipe_resource_reference(&target->buffer, res); 767 target->context = pipe; 768 target->buffer_offset = buffer_offset; 769 target->buffer_size = buffer_size; 770 771 return target; 772} 773 774static void 775ilo_set_stream_output_targets(struct pipe_context *pipe, 776 unsigned num_targets, 777 struct pipe_stream_output_target **targets, 778 unsigned append_bitmask) 779{ 780 struct ilo_context *ilo = ilo_context(pipe); 781 unsigned i; 782 783 if (!targets) 784 num_targets = 0; 785 786 for (i = 0; i < num_targets; i++) { 787 pipe_so_target_reference(&ilo->stream_output_targets.targets[i], 788 targets[i]); 789 } 790 for (; i < ilo->stream_output_targets.num_targets; i++) 791 pipe_so_target_reference(&ilo->stream_output_targets.targets[i], NULL); 792 793 ilo->stream_output_targets.num_targets = num_targets; 794 ilo->stream_output_targets.append_bitmask = append_bitmask; 795 796 ilo->dirty |= ILO_DIRTY_STREAM_OUTPUT_TARGETS; 797} 798 799static void 800ilo_stream_output_target_destroy(struct pipe_context *pipe, 801 struct pipe_stream_output_target *target) 802{ 803 pipe_resource_reference(&target->buffer, NULL); 804 FREE(target); 805} 806 807static struct pipe_sampler_view * 808ilo_create_sampler_view(struct pipe_context *pipe, 809 struct pipe_resource *res, 810 const struct pipe_sampler_view *templ) 811{ 812 struct pipe_sampler_view *view; 813 814 view = MALLOC_STRUCT(pipe_sampler_view); 815 assert(view); 816 817 *view = *templ; 818 pipe_reference_init(&view->reference, 1); 819 view->texture = NULL; 820 pipe_resource_reference(&view->texture, res); 821 view->context = pipe; 822 823 return view; 824} 825 826static void 827ilo_sampler_view_destroy(struct pipe_context *pipe, 828 struct pipe_sampler_view *view) 829{ 830 pipe_resource_reference(&view->texture, NULL); 831 FREE(view); 832} 833 834static struct pipe_surface * 835ilo_create_surface(struct pipe_context *pipe, 836 struct pipe_resource *res, 837 const struct pipe_surface *templ) 838{ 839 struct pipe_surface *surface; 840 841 surface = MALLOC_STRUCT(pipe_surface); 842 assert(surface); 843 844 *surface = *templ; 845 pipe_reference_init(&surface->reference, 1); 846 surface->texture = NULL; 847 pipe_resource_reference(&surface->texture, res); 848 849 surface->context = pipe; 850 surface->width = u_minify(res->width0, surface->u.tex.level); 851 surface->height = u_minify(res->height0, surface->u.tex.level); 852 853 return surface; 854} 855 856static void 857ilo_surface_destroy(struct pipe_context *pipe, 858 struct pipe_surface *surface) 859{ 860 pipe_resource_reference(&surface->texture, NULL); 861 FREE(surface); 862} 863 864static void * 865ilo_create_compute_state(struct pipe_context *pipe, 866 const struct pipe_compute_state *state) 867{ 868 struct ilo_context *ilo = ilo_context(pipe); 869 return ilo_shader_state_create(ilo, PIPE_SHADER_COMPUTE, state); 870} 871 872static void 873ilo_bind_compute_state(struct pipe_context *pipe, void *state) 874{ 875 struct ilo_context *ilo = ilo_context(pipe); 876 877 ilo->compute = state; 878 879 ilo->dirty |= ILO_DIRTY_COMPUTE; 880} 881 882static void 883ilo_delete_compute_state(struct pipe_context *pipe, void *state) 884{ 885 struct ilo_shader_state *cs = (struct ilo_shader_state *) state; 886 ilo_shader_state_destroy(cs); 887} 888 889static void 890ilo_set_compute_resources(struct pipe_context *pipe, 891 unsigned start, unsigned count, 892 struct pipe_surface **surfaces) 893{ 894 struct ilo_context *ilo = ilo_context(pipe); 895 struct pipe_surface **dst = ilo->compute_resources.surfaces; 896 unsigned i; 897 898 assert(start + count <= Elements(ilo->compute_resources.surfaces)); 899 900 dst += start; 901 if (surfaces) { 902 for (i = 0; i < count; i++) 903 pipe_surface_reference(&dst[i], surfaces[i]); 904 } 905 else { 906 for (i = 0; i < count; i++) 907 pipe_surface_reference(&dst[i], NULL); 908 } 909 910 if (ilo->compute_resources.num_surfaces <= start + count) { 911 count += start; 912 913 while (count > 0 && !ilo->compute_resources.surfaces[count - 1]) 914 count--; 915 916 ilo->compute_resources.num_surfaces = count; 917 } 918 919 ilo->dirty |= ILO_DIRTY_COMPUTE_RESOURCES; 920} 921 922static void 923ilo_set_global_binding(struct pipe_context *pipe, 924 unsigned start, unsigned count, 925 struct pipe_resource **resources, 926 uint32_t **handles) 927{ 928 struct ilo_context *ilo = ilo_context(pipe); 929 struct pipe_resource **dst = ilo->global_binding.resources; 930 unsigned i; 931 932 assert(start + count <= Elements(ilo->global_binding.resources)); 933 934 dst += start; 935 if (resources) { 936 for (i = 0; i < count; i++) 937 pipe_resource_reference(&dst[i], resources[i]); 938 } 939 else { 940 for (i = 0; i < count; i++) 941 pipe_resource_reference(&dst[i], NULL); 942 } 943 944 if (ilo->global_binding.num_resources <= start + count) { 945 count += start; 946 947 while (count > 0 && !ilo->global_binding.resources[count - 1]) 948 count--; 949 950 ilo->global_binding.num_resources = count; 951 } 952 953 ilo->dirty |= ILO_DIRTY_GLOBAL_BINDING; 954} 955 956/** 957 * Initialize state-related functions. 958 */ 959void 960ilo_init_state_functions(struct ilo_context *ilo) 961{ 962 STATIC_ASSERT(ILO_STATE_COUNT <= 32); 963 964 ilo->base.create_blend_state = ilo_create_blend_state; 965 ilo->base.bind_blend_state = ilo_bind_blend_state; 966 ilo->base.delete_blend_state = ilo_delete_blend_state; 967 ilo->base.create_sampler_state = ilo_create_sampler_state; 968 ilo->base.bind_fragment_sampler_states = ilo_bind_fragment_sampler_states; 969 ilo->base.bind_vertex_sampler_states = ilo_bind_vertex_sampler_states; 970 ilo->base.bind_geometry_sampler_states = ilo_bind_geometry_sampler_states; 971 ilo->base.bind_compute_sampler_states = ilo_bind_compute_sampler_states; 972 ilo->base.delete_sampler_state = ilo_delete_sampler_state; 973 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state; 974 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state; 975 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state; 976 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state; 977 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state; 978 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state; 979 ilo->base.create_fs_state = ilo_create_fs_state; 980 ilo->base.bind_fs_state = ilo_bind_fs_state; 981 ilo->base.delete_fs_state = ilo_delete_fs_state; 982 ilo->base.create_vs_state = ilo_create_vs_state; 983 ilo->base.bind_vs_state = ilo_bind_vs_state; 984 ilo->base.delete_vs_state = ilo_delete_vs_state; 985 ilo->base.create_gs_state = ilo_create_gs_state; 986 ilo->base.bind_gs_state = ilo_bind_gs_state; 987 ilo->base.delete_gs_state = ilo_delete_gs_state; 988 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state; 989 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state; 990 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state; 991 992 ilo->base.set_blend_color = ilo_set_blend_color; 993 ilo->base.set_stencil_ref = ilo_set_stencil_ref; 994 ilo->base.set_sample_mask = ilo_set_sample_mask; 995 ilo->base.set_clip_state = ilo_set_clip_state; 996 ilo->base.set_constant_buffer = ilo_set_constant_buffer; 997 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state; 998 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple; 999 ilo->base.set_scissor_states = ilo_set_scissor_states; 1000 ilo->base.set_viewport_states = ilo_set_viewport_states; 1001 ilo->base.set_fragment_sampler_views = ilo_set_fragment_sampler_views; 1002 ilo->base.set_vertex_sampler_views = ilo_set_vertex_sampler_views; 1003 ilo->base.set_geometry_sampler_views = ilo_set_geometry_sampler_views; 1004 ilo->base.set_compute_sampler_views = ilo_set_compute_sampler_views; 1005 ilo->base.set_shader_resources = ilo_set_shader_resources; 1006 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers; 1007 ilo->base.set_index_buffer = ilo_set_index_buffer; 1008 1009 ilo->base.create_stream_output_target = ilo_create_stream_output_target; 1010 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy; 1011 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets; 1012 1013 ilo->base.create_sampler_view = ilo_create_sampler_view; 1014 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy; 1015 1016 ilo->base.create_surface = ilo_create_surface; 1017 ilo->base.surface_destroy = ilo_surface_destroy; 1018 1019 ilo->base.create_compute_state = ilo_create_compute_state; 1020 ilo->base.bind_compute_state = ilo_bind_compute_state; 1021 ilo->base.delete_compute_state = ilo_delete_compute_state; 1022 ilo->base.set_compute_resources = ilo_set_compute_resources; 1023 ilo->base.set_global_binding = ilo_set_global_binding; 1024} 1025