1 /************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /** 29 * @file 30 * 31 * Wrap the cso cache & hash mechanisms in a simplified 32 * pipe-driver-specific interface. 33 * 34 * @author Zack Rusin <zackr (at) vmware.com> 35 * @author Keith Whitwell <keithw (at) vmware.com> 36 */ 37 38 #include "pipe/p_state.h" 39 #include "util/u_draw.h" 40 #include "util/u_framebuffer.h" 41 #include "util/u_inlines.h" 42 #include "util/u_math.h" 43 #include "util/u_memory.h" 44 #include "util/u_vbuf.h" 45 #include "tgsi/tgsi_parse.h" 46 47 #include "cso_cache/cso_context.h" 48 #include "cso_cache/cso_cache.h" 49 #include "cso_cache/cso_hash.h" 50 #include "cso_context.h" 51 52 53 /** 54 * Per-shader sampler information. 55 */ 56 struct sampler_info 57 { 58 struct cso_sampler *cso_samplers[PIPE_MAX_SAMPLERS]; 59 void *samplers[PIPE_MAX_SAMPLERS]; 60 }; 61 62 63 64 struct cso_context { 65 struct pipe_context *pipe; 66 struct cso_cache *cache; 67 struct u_vbuf *vbuf; 68 69 boolean has_geometry_shader; 70 boolean has_tessellation; 71 boolean has_compute_shader; 72 boolean has_streamout; 73 74 unsigned saved_state; /**< bitmask of CSO_BIT_x flags */ 75 76 struct pipe_sampler_view *fragment_views[PIPE_MAX_SHADER_SAMPLER_VIEWS]; 77 unsigned nr_fragment_views; 78 79 struct pipe_sampler_view *fragment_views_saved[PIPE_MAX_SHADER_SAMPLER_VIEWS]; 80 unsigned nr_fragment_views_saved; 81 82 struct sampler_info fragment_samplers_saved; 83 struct sampler_info samplers[PIPE_SHADER_TYPES]; 84 85 /* Temporary number until cso_single_sampler_done is called. 86 * It tracks the highest sampler seen in cso_single_sampler. 87 */ 88 int max_sampler_seen; 89 90 struct pipe_vertex_buffer aux_vertex_buffer_current; 91 struct pipe_vertex_buffer aux_vertex_buffer_saved; 92 unsigned aux_vertex_buffer_index; 93 94 struct pipe_constant_buffer aux_constbuf_current[PIPE_SHADER_TYPES]; 95 struct pipe_constant_buffer aux_constbuf_saved[PIPE_SHADER_TYPES]; 96 97 struct pipe_image_view fragment_image0_current; 98 struct pipe_image_view fragment_image0_saved; 99 100 unsigned nr_so_targets; 101 struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; 102 103 unsigned nr_so_targets_saved; 104 struct pipe_stream_output_target *so_targets_saved[PIPE_MAX_SO_BUFFERS]; 105 106 /** Current and saved state. 107 * The saved state is used as a 1-deep stack. 108 */ 109 void *blend, *blend_saved; 110 void *depth_stencil, *depth_stencil_saved; 111 void *rasterizer, *rasterizer_saved; 112 void *fragment_shader, *fragment_shader_saved; 113 void *vertex_shader, *vertex_shader_saved; 114 void *geometry_shader, *geometry_shader_saved; 115 void *tessctrl_shader, *tessctrl_shader_saved; 116 void *tesseval_shader, *tesseval_shader_saved; 117 void *compute_shader; 118 void *velements, *velements_saved; 119 struct pipe_query *render_condition, *render_condition_saved; 120 uint render_condition_mode, render_condition_mode_saved; 121 boolean render_condition_cond, render_condition_cond_saved; 122 123 struct pipe_framebuffer_state fb, fb_saved; 124 struct pipe_viewport_state vp, vp_saved; 125 struct pipe_blend_color blend_color; 126 unsigned sample_mask, sample_mask_saved; 127 unsigned min_samples, min_samples_saved; 128 struct pipe_stencil_ref stencil_ref, stencil_ref_saved; 129 }; 130 131 struct pipe_context *cso_get_pipe_context(struct cso_context *cso) 132 { 133 return cso->pipe; 134 } 135 136 static boolean delete_blend_state(struct cso_context *ctx, void *state) 137 { 138 struct cso_blend *cso = (struct cso_blend *)state; 139 140 if (ctx->blend == cso->data) 141 return FALSE; 142 143 if (cso->delete_state) 144 cso->delete_state(cso->context, cso->data); 145 FREE(state); 146 return TRUE; 147 } 148 149 static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state) 150 { 151 struct cso_depth_stencil_alpha *cso = 152 (struct cso_depth_stencil_alpha *)state; 153 154 if (ctx->depth_stencil == cso->data) 155 return FALSE; 156 157 if (cso->delete_state) 158 cso->delete_state(cso->context, cso->data); 159 FREE(state); 160 161 return TRUE; 162 } 163 164 static boolean delete_sampler_state(struct cso_context *ctx, void *state) 165 { 166 struct cso_sampler *cso = (struct cso_sampler *)state; 167 if (cso->delete_state) 168 cso->delete_state(cso->context, cso->data); 169 FREE(state); 170 return TRUE; 171 } 172 173 static boolean delete_rasterizer_state(struct cso_context *ctx, void *state) 174 { 175 struct cso_rasterizer *cso = (struct cso_rasterizer *)state; 176 177 if (ctx->rasterizer == cso->data) 178 return FALSE; 179 if (cso->delete_state) 180 cso->delete_state(cso->context, cso->data); 181 FREE(state); 182 return TRUE; 183 } 184 185 static boolean delete_vertex_elements(struct cso_context *ctx, 186 void *state) 187 { 188 struct cso_velements *cso = (struct cso_velements *)state; 189 190 if (ctx->velements == cso->data) 191 return FALSE; 192 193 if (cso->delete_state) 194 cso->delete_state(cso->context, cso->data); 195 FREE(state); 196 return TRUE; 197 } 198 199 200 static inline boolean delete_cso(struct cso_context *ctx, 201 void *state, enum cso_cache_type type) 202 { 203 switch (type) { 204 case CSO_BLEND: 205 return delete_blend_state(ctx, state); 206 case CSO_SAMPLER: 207 return delete_sampler_state(ctx, state); 208 case CSO_DEPTH_STENCIL_ALPHA: 209 return delete_depth_stencil_state(ctx, state); 210 case CSO_RASTERIZER: 211 return delete_rasterizer_state(ctx, state); 212 case CSO_VELEMENTS: 213 return delete_vertex_elements(ctx, state); 214 default: 215 assert(0); 216 FREE(state); 217 } 218 return FALSE; 219 } 220 221 static inline void 222 sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, 223 int max_size, void *user_data) 224 { 225 struct cso_context *ctx = (struct cso_context *)user_data; 226 /* if we're approach the maximum size, remove fourth of the entries 227 * otherwise every subsequent call will go through the same */ 228 int hash_size = cso_hash_size(hash); 229 int max_entries = (max_size > hash_size) ? max_size : hash_size; 230 int to_remove = (max_size < max_entries) * max_entries/4; 231 struct cso_hash_iter iter; 232 struct cso_sampler **samplers_to_restore = NULL; 233 unsigned to_restore = 0; 234 235 if (hash_size > max_size) 236 to_remove += hash_size - max_size; 237 238 if (to_remove == 0) 239 return; 240 241 if (type == CSO_SAMPLER) { 242 int i, j; 243 244 samplers_to_restore = MALLOC(PIPE_SHADER_TYPES * PIPE_MAX_SAMPLERS * 245 sizeof(*samplers_to_restore)); 246 247 /* Temporarily remove currently bound sampler states from the hash 248 * table, to prevent them from being deleted 249 */ 250 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 251 for (j = 0; j < PIPE_MAX_SAMPLERS; j++) { 252 struct cso_sampler *sampler = ctx->samplers[i].cso_samplers[j]; 253 254 if (sampler && cso_hash_take(hash, sampler->hash_key)) 255 samplers_to_restore[to_restore++] = sampler; 256 } 257 } 258 } 259 260 iter = cso_hash_first_node(hash); 261 while (to_remove) { 262 /*remove elements until we're good */ 263 /*fixme: currently we pick the nodes to remove at random*/ 264 void *cso = cso_hash_iter_data(iter); 265 266 if (!cso) 267 break; 268 269 if (delete_cso(ctx, cso, type)) { 270 iter = cso_hash_erase(hash, iter); 271 --to_remove; 272 } else 273 iter = cso_hash_iter_next(iter); 274 } 275 276 if (type == CSO_SAMPLER) { 277 /* Put currently bound sampler states back into the hash table */ 278 while (to_restore--) { 279 struct cso_sampler *sampler = samplers_to_restore[to_restore]; 280 281 cso_hash_insert(hash, sampler->hash_key, sampler); 282 } 283 284 FREE(samplers_to_restore); 285 } 286 } 287 288 static void cso_init_vbuf(struct cso_context *cso, unsigned flags) 289 { 290 struct u_vbuf_caps caps; 291 292 /* Install u_vbuf if there is anything unsupported. */ 293 if (u_vbuf_get_caps(cso->pipe->screen, &caps, flags)) { 294 cso->vbuf = u_vbuf_create(cso->pipe, &caps, 295 cso->aux_vertex_buffer_index); 296 } 297 } 298 299 struct cso_context * 300 cso_create_context(struct pipe_context *pipe, unsigned u_vbuf_flags) 301 { 302 struct cso_context *ctx = CALLOC_STRUCT(cso_context); 303 if (!ctx) 304 return NULL; 305 306 ctx->cache = cso_cache_create(); 307 if (ctx->cache == NULL) 308 goto out; 309 cso_cache_set_sanitize_callback(ctx->cache, 310 sanitize_hash, 311 ctx); 312 313 ctx->pipe = pipe; 314 ctx->sample_mask = ~0; 315 316 ctx->aux_vertex_buffer_index = 0; /* 0 for now */ 317 318 cso_init_vbuf(ctx, u_vbuf_flags); 319 320 /* Enable for testing: */ 321 if (0) cso_set_maximum_cache_size( ctx->cache, 4 ); 322 323 if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 324 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { 325 ctx->has_geometry_shader = TRUE; 326 } 327 if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL, 328 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { 329 ctx->has_tessellation = TRUE; 330 } 331 if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE, 332 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { 333 int supported_irs = 334 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE, 335 PIPE_SHADER_CAP_SUPPORTED_IRS); 336 if (supported_irs & (1 << PIPE_SHADER_IR_TGSI)) { 337 ctx->has_compute_shader = TRUE; 338 } 339 } 340 if (pipe->screen->get_param(pipe->screen, 341 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) { 342 ctx->has_streamout = TRUE; 343 } 344 345 ctx->max_sampler_seen = -1; 346 return ctx; 347 348 out: 349 cso_destroy_context( ctx ); 350 return NULL; 351 } 352 353 /** 354 * Free the CSO context. 355 */ 356 void cso_destroy_context( struct cso_context *ctx ) 357 { 358 unsigned i; 359 360 if (ctx->pipe) { 361 ctx->pipe->bind_blend_state( ctx->pipe, NULL ); 362 ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL ); 363 364 { 365 static struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS] = { NULL }; 366 static void *zeros[PIPE_MAX_SAMPLERS] = { NULL }; 367 struct pipe_screen *scr = ctx->pipe->screen; 368 enum pipe_shader_type sh; 369 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { 370 int maxsam = scr->get_shader_param(scr, sh, 371 PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); 372 int maxview = scr->get_shader_param(scr, sh, 373 PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS); 374 assert(maxsam <= PIPE_MAX_SAMPLERS); 375 assert(maxview <= PIPE_MAX_SHADER_SAMPLER_VIEWS); 376 if (maxsam > 0) { 377 ctx->pipe->bind_sampler_states(ctx->pipe, sh, 0, maxsam, zeros); 378 } 379 if (maxview > 0) { 380 ctx->pipe->set_sampler_views(ctx->pipe, sh, 0, maxview, views); 381 } 382 } 383 } 384 385 ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); 386 ctx->pipe->bind_fs_state( ctx->pipe, NULL ); 387 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, NULL); 388 ctx->pipe->bind_vs_state( ctx->pipe, NULL ); 389 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, NULL); 390 if (ctx->has_geometry_shader) { 391 ctx->pipe->bind_gs_state(ctx->pipe, NULL); 392 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_GEOMETRY, 0, NULL); 393 } 394 if (ctx->has_tessellation) { 395 ctx->pipe->bind_tcs_state(ctx->pipe, NULL); 396 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_CTRL, 0, NULL); 397 ctx->pipe->bind_tes_state(ctx->pipe, NULL); 398 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_TESS_EVAL, 0, NULL); 399 } 400 if (ctx->has_compute_shader) { 401 ctx->pipe->bind_compute_state(ctx->pipe, NULL); 402 ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_COMPUTE, 0, NULL); 403 } 404 ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL ); 405 406 if (ctx->has_streamout) 407 ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, NULL); 408 } 409 410 for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) { 411 pipe_sampler_view_reference(&ctx->fragment_views[i], NULL); 412 pipe_sampler_view_reference(&ctx->fragment_views_saved[i], NULL); 413 } 414 415 util_unreference_framebuffer_state(&ctx->fb); 416 util_unreference_framebuffer_state(&ctx->fb_saved); 417 418 pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_current); 419 pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_saved); 420 421 for (i = 0; i < PIPE_SHADER_TYPES; i++) { 422 pipe_resource_reference(&ctx->aux_constbuf_current[i].buffer, NULL); 423 pipe_resource_reference(&ctx->aux_constbuf_saved[i].buffer, NULL); 424 } 425 426 pipe_resource_reference(&ctx->fragment_image0_current.resource, NULL); 427 pipe_resource_reference(&ctx->fragment_image0_saved.resource, NULL); 428 429 for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 430 pipe_so_target_reference(&ctx->so_targets[i], NULL); 431 pipe_so_target_reference(&ctx->so_targets_saved[i], NULL); 432 } 433 434 if (ctx->cache) { 435 cso_cache_delete( ctx->cache ); 436 ctx->cache = NULL; 437 } 438 439 if (ctx->vbuf) 440 u_vbuf_destroy(ctx->vbuf); 441 FREE( ctx ); 442 } 443 444 445 /* Those function will either find the state of the given template 446 * in the cache or they will create a new state from the given 447 * template, insert it in the cache and return it. 448 */ 449 450 /* 451 * If the driver returns 0 from the create method then they will assign 452 * the data member of the cso to be the template itself. 453 */ 454 455 enum pipe_error cso_set_blend(struct cso_context *ctx, 456 const struct pipe_blend_state *templ) 457 { 458 unsigned key_size, hash_key; 459 struct cso_hash_iter iter; 460 void *handle; 461 462 key_size = templ->independent_blend_enable ? 463 sizeof(struct pipe_blend_state) : 464 (char *)&(templ->rt[1]) - (char *)templ; 465 hash_key = cso_construct_key((void*)templ, key_size); 466 iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND, 467 (void*)templ, key_size); 468 469 if (cso_hash_iter_is_null(iter)) { 470 struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); 471 if (!cso) 472 return PIPE_ERROR_OUT_OF_MEMORY; 473 474 memset(&cso->state, 0, sizeof cso->state); 475 memcpy(&cso->state, templ, key_size); 476 cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); 477 cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; 478 cso->context = ctx->pipe; 479 480 iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); 481 if (cso_hash_iter_is_null(iter)) { 482 FREE(cso); 483 return PIPE_ERROR_OUT_OF_MEMORY; 484 } 485 486 handle = cso->data; 487 } 488 else { 489 handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data; 490 } 491 492 if (ctx->blend != handle) { 493 ctx->blend = handle; 494 ctx->pipe->bind_blend_state(ctx->pipe, handle); 495 } 496 return PIPE_OK; 497 } 498 499 static void 500 cso_save_blend(struct cso_context *ctx) 501 { 502 assert(!ctx->blend_saved); 503 ctx->blend_saved = ctx->blend; 504 } 505 506 static void 507 cso_restore_blend(struct cso_context *ctx) 508 { 509 if (ctx->blend != ctx->blend_saved) { 510 ctx->blend = ctx->blend_saved; 511 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved); 512 } 513 ctx->blend_saved = NULL; 514 } 515 516 517 518 enum pipe_error 519 cso_set_depth_stencil_alpha(struct cso_context *ctx, 520 const struct pipe_depth_stencil_alpha_state *templ) 521 { 522 unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state); 523 unsigned hash_key = cso_construct_key((void*)templ, key_size); 524 struct cso_hash_iter iter = cso_find_state_template(ctx->cache, 525 hash_key, 526 CSO_DEPTH_STENCIL_ALPHA, 527 (void*)templ, key_size); 528 void *handle; 529 530 if (cso_hash_iter_is_null(iter)) { 531 struct cso_depth_stencil_alpha *cso = 532 MALLOC(sizeof(struct cso_depth_stencil_alpha)); 533 if (!cso) 534 return PIPE_ERROR_OUT_OF_MEMORY; 535 536 memcpy(&cso->state, templ, sizeof(*templ)); 537 cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, 538 &cso->state); 539 cso->delete_state = 540 (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; 541 cso->context = ctx->pipe; 542 543 iter = cso_insert_state(ctx->cache, hash_key, 544 CSO_DEPTH_STENCIL_ALPHA, cso); 545 if (cso_hash_iter_is_null(iter)) { 546 FREE(cso); 547 return PIPE_ERROR_OUT_OF_MEMORY; 548 } 549 550 handle = cso->data; 551 } 552 else { 553 handle = ((struct cso_depth_stencil_alpha *) 554 cso_hash_iter_data(iter))->data; 555 } 556 557 if (ctx->depth_stencil != handle) { 558 ctx->depth_stencil = handle; 559 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); 560 } 561 return PIPE_OK; 562 } 563 564 static void 565 cso_save_depth_stencil_alpha(struct cso_context *ctx) 566 { 567 assert(!ctx->depth_stencil_saved); 568 ctx->depth_stencil_saved = ctx->depth_stencil; 569 } 570 571 static void 572 cso_restore_depth_stencil_alpha(struct cso_context *ctx) 573 { 574 if (ctx->depth_stencil != ctx->depth_stencil_saved) { 575 ctx->depth_stencil = ctx->depth_stencil_saved; 576 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, 577 ctx->depth_stencil_saved); 578 } 579 ctx->depth_stencil_saved = NULL; 580 } 581 582 583 584 enum pipe_error cso_set_rasterizer(struct cso_context *ctx, 585 const struct pipe_rasterizer_state *templ) 586 { 587 unsigned key_size = sizeof(struct pipe_rasterizer_state); 588 unsigned hash_key = cso_construct_key((void*)templ, key_size); 589 struct cso_hash_iter iter = cso_find_state_template(ctx->cache, 590 hash_key, 591 CSO_RASTERIZER, 592 (void*)templ, key_size); 593 void *handle = NULL; 594 595 /* We can't have both point_quad_rasterization (sprites) and point_smooth 596 * (round AA points) enabled at the same time. 597 */ 598 assert(!(templ->point_quad_rasterization && templ->point_smooth)); 599 600 if (cso_hash_iter_is_null(iter)) { 601 struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); 602 if (!cso) 603 return PIPE_ERROR_OUT_OF_MEMORY; 604 605 memcpy(&cso->state, templ, sizeof(*templ)); 606 cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); 607 cso->delete_state = 608 (cso_state_callback)ctx->pipe->delete_rasterizer_state; 609 cso->context = ctx->pipe; 610 611 iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); 612 if (cso_hash_iter_is_null(iter)) { 613 FREE(cso); 614 return PIPE_ERROR_OUT_OF_MEMORY; 615 } 616 617 handle = cso->data; 618 } 619 else { 620 handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data; 621 } 622 623 if (ctx->rasterizer != handle) { 624 ctx->rasterizer = handle; 625 ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); 626 } 627 return PIPE_OK; 628 } 629 630 static void 631 cso_save_rasterizer(struct cso_context *ctx) 632 { 633 assert(!ctx->rasterizer_saved); 634 ctx->rasterizer_saved = ctx->rasterizer; 635 } 636 637 static void 638 cso_restore_rasterizer(struct cso_context *ctx) 639 { 640 if (ctx->rasterizer != ctx->rasterizer_saved) { 641 ctx->rasterizer = ctx->rasterizer_saved; 642 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved); 643 } 644 ctx->rasterizer_saved = NULL; 645 } 646 647 648 void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) 649 { 650 if (ctx->fragment_shader != handle) { 651 ctx->fragment_shader = handle; 652 ctx->pipe->bind_fs_state(ctx->pipe, handle); 653 } 654 } 655 656 void cso_delete_fragment_shader(struct cso_context *ctx, void *handle ) 657 { 658 if (handle == ctx->fragment_shader) { 659 /* unbind before deleting */ 660 ctx->pipe->bind_fs_state(ctx->pipe, NULL); 661 ctx->fragment_shader = NULL; 662 } 663 ctx->pipe->delete_fs_state(ctx->pipe, handle); 664 } 665 666 static void 667 cso_save_fragment_shader(struct cso_context *ctx) 668 { 669 assert(!ctx->fragment_shader_saved); 670 ctx->fragment_shader_saved = ctx->fragment_shader; 671 } 672 673 static void 674 cso_restore_fragment_shader(struct cso_context *ctx) 675 { 676 if (ctx->fragment_shader_saved != ctx->fragment_shader) { 677 ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved); 678 ctx->fragment_shader = ctx->fragment_shader_saved; 679 } 680 ctx->fragment_shader_saved = NULL; 681 } 682 683 684 void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle) 685 { 686 if (ctx->vertex_shader != handle) { 687 ctx->vertex_shader = handle; 688 ctx->pipe->bind_vs_state(ctx->pipe, handle); 689 } 690 } 691 692 void cso_delete_vertex_shader(struct cso_context *ctx, void *handle ) 693 { 694 if (handle == ctx->vertex_shader) { 695 /* unbind before deleting */ 696 ctx->pipe->bind_vs_state(ctx->pipe, NULL); 697 ctx->vertex_shader = NULL; 698 } 699 ctx->pipe->delete_vs_state(ctx->pipe, handle); 700 } 701 702 static void 703 cso_save_vertex_shader(struct cso_context *ctx) 704 { 705 assert(!ctx->vertex_shader_saved); 706 ctx->vertex_shader_saved = ctx->vertex_shader; 707 } 708 709 static void 710 cso_restore_vertex_shader(struct cso_context *ctx) 711 { 712 if (ctx->vertex_shader_saved != ctx->vertex_shader) { 713 ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved); 714 ctx->vertex_shader = ctx->vertex_shader_saved; 715 } 716 ctx->vertex_shader_saved = NULL; 717 } 718 719 720 void cso_set_framebuffer(struct cso_context *ctx, 721 const struct pipe_framebuffer_state *fb) 722 { 723 if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) { 724 util_copy_framebuffer_state(&ctx->fb, fb); 725 ctx->pipe->set_framebuffer_state(ctx->pipe, fb); 726 } 727 } 728 729 static void 730 cso_save_framebuffer(struct cso_context *ctx) 731 { 732 util_copy_framebuffer_state(&ctx->fb_saved, &ctx->fb); 733 } 734 735 static void 736 cso_restore_framebuffer(struct cso_context *ctx) 737 { 738 if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) { 739 util_copy_framebuffer_state(&ctx->fb, &ctx->fb_saved); 740 ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb); 741 util_unreference_framebuffer_state(&ctx->fb_saved); 742 } 743 } 744 745 746 void cso_set_viewport(struct cso_context *ctx, 747 const struct pipe_viewport_state *vp) 748 { 749 if (memcmp(&ctx->vp, vp, sizeof(*vp))) { 750 ctx->vp = *vp; 751 ctx->pipe->set_viewport_states(ctx->pipe, 0, 1, vp); 752 } 753 } 754 755 /** 756 * Setup viewport state for given width and height (position is always (0,0)). 757 * Invert the Y axis if 'invert' is true. 758 */ 759 void 760 cso_set_viewport_dims(struct cso_context *ctx, 761 float width, float height, boolean invert) 762 { 763 struct pipe_viewport_state vp; 764 vp.scale[0] = width * 0.5f; 765 vp.scale[1] = height * (invert ? -0.5f : 0.5f); 766 vp.scale[2] = 0.5f; 767 vp.translate[0] = 0.5f * width; 768 vp.translate[1] = 0.5f * height; 769 vp.translate[2] = 0.5f; 770 cso_set_viewport(ctx, &vp); 771 } 772 773 static void 774 cso_save_viewport(struct cso_context *ctx) 775 { 776 ctx->vp_saved = ctx->vp; 777 } 778 779 780 static void 781 cso_restore_viewport(struct cso_context *ctx) 782 { 783 if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) { 784 ctx->vp = ctx->vp_saved; 785 ctx->pipe->set_viewport_states(ctx->pipe, 0, 1, &ctx->vp); 786 } 787 } 788 789 790 void cso_set_blend_color(struct cso_context *ctx, 791 const struct pipe_blend_color *bc) 792 { 793 if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) { 794 ctx->blend_color = *bc; 795 ctx->pipe->set_blend_color(ctx->pipe, bc); 796 } 797 } 798 799 void cso_set_sample_mask(struct cso_context *ctx, unsigned sample_mask) 800 { 801 if (ctx->sample_mask != sample_mask) { 802 ctx->sample_mask = sample_mask; 803 ctx->pipe->set_sample_mask(ctx->pipe, sample_mask); 804 } 805 } 806 807 static void 808 cso_save_sample_mask(struct cso_context *ctx) 809 { 810 ctx->sample_mask_saved = ctx->sample_mask; 811 } 812 813 static void 814 cso_restore_sample_mask(struct cso_context *ctx) 815 { 816 cso_set_sample_mask(ctx, ctx->sample_mask_saved); 817 } 818 819 void cso_set_min_samples(struct cso_context *ctx, unsigned min_samples) 820 { 821 if (ctx->min_samples != min_samples && ctx->pipe->set_min_samples) { 822 ctx->min_samples = min_samples; 823 ctx->pipe->set_min_samples(ctx->pipe, min_samples); 824 } 825 } 826 827 static void 828 cso_save_min_samples(struct cso_context *ctx) 829 { 830 ctx->min_samples_saved = ctx->min_samples; 831 } 832 833 static void 834 cso_restore_min_samples(struct cso_context *ctx) 835 { 836 cso_set_min_samples(ctx, ctx->min_samples_saved); 837 } 838 839 void cso_set_stencil_ref(struct cso_context *ctx, 840 const struct pipe_stencil_ref *sr) 841 { 842 if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) { 843 ctx->stencil_ref = *sr; 844 ctx->pipe->set_stencil_ref(ctx->pipe, sr); 845 } 846 } 847 848 static void 849 cso_save_stencil_ref(struct cso_context *ctx) 850 { 851 ctx->stencil_ref_saved = ctx->stencil_ref; 852 } 853 854 855 static void 856 cso_restore_stencil_ref(struct cso_context *ctx) 857 { 858 if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved, 859 sizeof(ctx->stencil_ref))) { 860 ctx->stencil_ref = ctx->stencil_ref_saved; 861 ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref); 862 } 863 } 864 865 void cso_set_render_condition(struct cso_context *ctx, 866 struct pipe_query *query, 867 boolean condition, 868 enum pipe_render_cond_flag mode) 869 { 870 struct pipe_context *pipe = ctx->pipe; 871 872 if (ctx->render_condition != query || 873 ctx->render_condition_mode != mode || 874 ctx->render_condition_cond != condition) { 875 pipe->render_condition(pipe, query, condition, mode); 876 ctx->render_condition = query; 877 ctx->render_condition_cond = condition; 878 ctx->render_condition_mode = mode; 879 } 880 } 881 882 static void 883 cso_save_render_condition(struct cso_context *ctx) 884 { 885 ctx->render_condition_saved = ctx->render_condition; 886 ctx->render_condition_cond_saved = ctx->render_condition_cond; 887 ctx->render_condition_mode_saved = ctx->render_condition_mode; 888 } 889 890 static void 891 cso_restore_render_condition(struct cso_context *ctx) 892 { 893 cso_set_render_condition(ctx, ctx->render_condition_saved, 894 ctx->render_condition_cond_saved, 895 ctx->render_condition_mode_saved); 896 } 897 898 void cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle) 899 { 900 assert(ctx->has_geometry_shader || !handle); 901 902 if (ctx->has_geometry_shader && ctx->geometry_shader != handle) { 903 ctx->geometry_shader = handle; 904 ctx->pipe->bind_gs_state(ctx->pipe, handle); 905 } 906 } 907 908 void cso_delete_geometry_shader(struct cso_context *ctx, void *handle) 909 { 910 if (handle == ctx->geometry_shader) { 911 /* unbind before deleting */ 912 ctx->pipe->bind_gs_state(ctx->pipe, NULL); 913 ctx->geometry_shader = NULL; 914 } 915 ctx->pipe->delete_gs_state(ctx->pipe, handle); 916 } 917 918 static void 919 cso_save_geometry_shader(struct cso_context *ctx) 920 { 921 if (!ctx->has_geometry_shader) { 922 return; 923 } 924 925 assert(!ctx->geometry_shader_saved); 926 ctx->geometry_shader_saved = ctx->geometry_shader; 927 } 928 929 static void 930 cso_restore_geometry_shader(struct cso_context *ctx) 931 { 932 if (!ctx->has_geometry_shader) { 933 return; 934 } 935 936 if (ctx->geometry_shader_saved != ctx->geometry_shader) { 937 ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved); 938 ctx->geometry_shader = ctx->geometry_shader_saved; 939 } 940 ctx->geometry_shader_saved = NULL; 941 } 942 943 void cso_set_tessctrl_shader_handle(struct cso_context *ctx, void *handle) 944 { 945 assert(ctx->has_tessellation || !handle); 946 947 if (ctx->has_tessellation && ctx->tessctrl_shader != handle) { 948 ctx->tessctrl_shader = handle; 949 ctx->pipe->bind_tcs_state(ctx->pipe, handle); 950 } 951 } 952 953 void cso_delete_tessctrl_shader(struct cso_context *ctx, void *handle) 954 { 955 if (handle == ctx->tessctrl_shader) { 956 /* unbind before deleting */ 957 ctx->pipe->bind_tcs_state(ctx->pipe, NULL); 958 ctx->tessctrl_shader = NULL; 959 } 960 ctx->pipe->delete_tcs_state(ctx->pipe, handle); 961 } 962 963 static void 964 cso_save_tessctrl_shader(struct cso_context *ctx) 965 { 966 if (!ctx->has_tessellation) { 967 return; 968 } 969 970 assert(!ctx->tessctrl_shader_saved); 971 ctx->tessctrl_shader_saved = ctx->tessctrl_shader; 972 } 973 974 static void 975 cso_restore_tessctrl_shader(struct cso_context *ctx) 976 { 977 if (!ctx->has_tessellation) { 978 return; 979 } 980 981 if (ctx->tessctrl_shader_saved != ctx->tessctrl_shader) { 982 ctx->pipe->bind_tcs_state(ctx->pipe, ctx->tessctrl_shader_saved); 983 ctx->tessctrl_shader = ctx->tessctrl_shader_saved; 984 } 985 ctx->tessctrl_shader_saved = NULL; 986 } 987 988 void cso_set_tesseval_shader_handle(struct cso_context *ctx, void *handle) 989 { 990 assert(ctx->has_tessellation || !handle); 991 992 if (ctx->has_tessellation && ctx->tesseval_shader != handle) { 993 ctx->tesseval_shader = handle; 994 ctx->pipe->bind_tes_state(ctx->pipe, handle); 995 } 996 } 997 998 void cso_delete_tesseval_shader(struct cso_context *ctx, void *handle) 999 { 1000 if (handle == ctx->tesseval_shader) { 1001 /* unbind before deleting */ 1002 ctx->pipe->bind_tes_state(ctx->pipe, NULL); 1003 ctx->tesseval_shader = NULL; 1004 } 1005 ctx->pipe->delete_tes_state(ctx->pipe, handle); 1006 } 1007 1008 static void 1009 cso_save_tesseval_shader(struct cso_context *ctx) 1010 { 1011 if (!ctx->has_tessellation) { 1012 return; 1013 } 1014 1015 assert(!ctx->tesseval_shader_saved); 1016 ctx->tesseval_shader_saved = ctx->tesseval_shader; 1017 } 1018 1019 static void 1020 cso_restore_tesseval_shader(struct cso_context *ctx) 1021 { 1022 if (!ctx->has_tessellation) { 1023 return; 1024 } 1025 1026 if (ctx->tesseval_shader_saved != ctx->tesseval_shader) { 1027 ctx->pipe->bind_tes_state(ctx->pipe, ctx->tesseval_shader_saved); 1028 ctx->tesseval_shader = ctx->tesseval_shader_saved; 1029 } 1030 ctx->tesseval_shader_saved = NULL; 1031 } 1032 1033 void cso_set_compute_shader_handle(struct cso_context *ctx, void *handle) 1034 { 1035 assert(ctx->has_compute_shader || !handle); 1036 1037 if (ctx->has_compute_shader && ctx->compute_shader != handle) { 1038 ctx->compute_shader = handle; 1039 ctx->pipe->bind_compute_state(ctx->pipe, handle); 1040 } 1041 } 1042 1043 void cso_delete_compute_shader(struct cso_context *ctx, void *handle) 1044 { 1045 if (handle == ctx->compute_shader) { 1046 /* unbind before deleting */ 1047 ctx->pipe->bind_compute_state(ctx->pipe, NULL); 1048 ctx->compute_shader = NULL; 1049 } 1050 ctx->pipe->delete_compute_state(ctx->pipe, handle); 1051 } 1052 1053 enum pipe_error 1054 cso_set_vertex_elements(struct cso_context *ctx, 1055 unsigned count, 1056 const struct pipe_vertex_element *states) 1057 { 1058 struct u_vbuf *vbuf = ctx->vbuf; 1059 unsigned key_size, hash_key; 1060 struct cso_hash_iter iter; 1061 void *handle; 1062 struct cso_velems_state velems_state; 1063 1064 if (vbuf) { 1065 u_vbuf_set_vertex_elements(vbuf, count, states); 1066 return PIPE_OK; 1067 } 1068 1069 /* Need to include the count into the stored state data too. 1070 * Otherwise first few count pipe_vertex_elements could be identical 1071 * even if count is different, and there's no guarantee the hash would 1072 * be different in that case neither. 1073 */ 1074 key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned); 1075 velems_state.count = count; 1076 memcpy(velems_state.velems, states, 1077 sizeof(struct pipe_vertex_element) * count); 1078 hash_key = cso_construct_key((void*)&velems_state, key_size); 1079 iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, 1080 (void*)&velems_state, key_size); 1081 1082 if (cso_hash_iter_is_null(iter)) { 1083 struct cso_velements *cso = MALLOC(sizeof(struct cso_velements)); 1084 if (!cso) 1085 return PIPE_ERROR_OUT_OF_MEMORY; 1086 1087 memcpy(&cso->state, &velems_state, key_size); 1088 cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, 1089 &cso->state.velems[0]); 1090 cso->delete_state = 1091 (cso_state_callback) ctx->pipe->delete_vertex_elements_state; 1092 cso->context = ctx->pipe; 1093 1094 iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso); 1095 if (cso_hash_iter_is_null(iter)) { 1096 FREE(cso); 1097 return PIPE_ERROR_OUT_OF_MEMORY; 1098 } 1099 1100 handle = cso->data; 1101 } 1102 else { 1103 handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data; 1104 } 1105 1106 if (ctx->velements != handle) { 1107 ctx->velements = handle; 1108 ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle); 1109 } 1110 return PIPE_OK; 1111 } 1112 1113 static void 1114 cso_save_vertex_elements(struct cso_context *ctx) 1115 { 1116 struct u_vbuf *vbuf = ctx->vbuf; 1117 1118 if (vbuf) { 1119 u_vbuf_save_vertex_elements(vbuf); 1120 return; 1121 } 1122 1123 assert(!ctx->velements_saved); 1124 ctx->velements_saved = ctx->velements; 1125 } 1126 1127 static void 1128 cso_restore_vertex_elements(struct cso_context *ctx) 1129 { 1130 struct u_vbuf *vbuf = ctx->vbuf; 1131 1132 if (vbuf) { 1133 u_vbuf_restore_vertex_elements(vbuf); 1134 return; 1135 } 1136 1137 if (ctx->velements != ctx->velements_saved) { 1138 ctx->velements = ctx->velements_saved; 1139 ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved); 1140 } 1141 ctx->velements_saved = NULL; 1142 } 1143 1144 /* vertex buffers */ 1145 1146 void cso_set_vertex_buffers(struct cso_context *ctx, 1147 unsigned start_slot, unsigned count, 1148 const struct pipe_vertex_buffer *buffers) 1149 { 1150 struct u_vbuf *vbuf = ctx->vbuf; 1151 1152 if (vbuf) { 1153 u_vbuf_set_vertex_buffers(vbuf, start_slot, count, buffers); 1154 return; 1155 } 1156 1157 /* Save what's in the auxiliary slot, so that we can save and restore it 1158 * for meta ops. */ 1159 if (start_slot <= ctx->aux_vertex_buffer_index && 1160 start_slot+count > ctx->aux_vertex_buffer_index) { 1161 if (buffers) { 1162 const struct pipe_vertex_buffer *vb = 1163 buffers + (ctx->aux_vertex_buffer_index - start_slot); 1164 1165 pipe_vertex_buffer_reference(&ctx->aux_vertex_buffer_current, vb); 1166 } else { 1167 pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_current); 1168 } 1169 } 1170 1171 ctx->pipe->set_vertex_buffers(ctx->pipe, start_slot, count, buffers); 1172 } 1173 1174 static void 1175 cso_save_aux_vertex_buffer_slot(struct cso_context *ctx) 1176 { 1177 struct u_vbuf *vbuf = ctx->vbuf; 1178 1179 if (vbuf) { 1180 u_vbuf_save_aux_vertex_buffer_slot(vbuf); 1181 return; 1182 } 1183 1184 pipe_vertex_buffer_reference(&ctx->aux_vertex_buffer_saved, 1185 &ctx->aux_vertex_buffer_current); 1186 } 1187 1188 static void 1189 cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx) 1190 { 1191 struct u_vbuf *vbuf = ctx->vbuf; 1192 1193 if (vbuf) { 1194 u_vbuf_restore_aux_vertex_buffer_slot(vbuf); 1195 return; 1196 } 1197 1198 cso_set_vertex_buffers(ctx, ctx->aux_vertex_buffer_index, 1, 1199 &ctx->aux_vertex_buffer_saved); 1200 pipe_vertex_buffer_unreference(&ctx->aux_vertex_buffer_saved); 1201 } 1202 1203 unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx) 1204 { 1205 return ctx->aux_vertex_buffer_index; 1206 } 1207 1208 1209 1210 void 1211 cso_single_sampler(struct cso_context *ctx, enum pipe_shader_type shader_stage, 1212 unsigned idx, const struct pipe_sampler_state *templ) 1213 { 1214 if (templ) { 1215 unsigned key_size = sizeof(struct pipe_sampler_state); 1216 unsigned hash_key = cso_construct_key((void*)templ, key_size); 1217 struct cso_sampler *cso; 1218 struct cso_hash_iter iter = 1219 cso_find_state_template(ctx->cache, 1220 hash_key, CSO_SAMPLER, 1221 (void *) templ, key_size); 1222 1223 if (cso_hash_iter_is_null(iter)) { 1224 cso = MALLOC(sizeof(struct cso_sampler)); 1225 if (!cso) 1226 return; 1227 1228 memcpy(&cso->state, templ, sizeof(*templ)); 1229 cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); 1230 cso->delete_state = 1231 (cso_state_callback) ctx->pipe->delete_sampler_state; 1232 cso->context = ctx->pipe; 1233 cso->hash_key = hash_key; 1234 1235 iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); 1236 if (cso_hash_iter_is_null(iter)) { 1237 FREE(cso); 1238 return; 1239 } 1240 } 1241 else { 1242 cso = cso_hash_iter_data(iter); 1243 } 1244 1245 ctx->samplers[shader_stage].cso_samplers[idx] = cso; 1246 ctx->samplers[shader_stage].samplers[idx] = cso->data; 1247 ctx->max_sampler_seen = MAX2(ctx->max_sampler_seen, (int)idx); 1248 } 1249 } 1250 1251 1252 /** 1253 * Send staged sampler state to the driver. 1254 */ 1255 void 1256 cso_single_sampler_done(struct cso_context *ctx, 1257 enum pipe_shader_type shader_stage) 1258 { 1259 struct sampler_info *info = &ctx->samplers[shader_stage]; 1260 1261 if (ctx->max_sampler_seen == -1) 1262 return; 1263 1264 ctx->pipe->bind_sampler_states(ctx->pipe, shader_stage, 0, 1265 ctx->max_sampler_seen + 1, 1266 info->samplers); 1267 ctx->max_sampler_seen = -1; 1268 } 1269 1270 1271 /* 1272 * If the function encouters any errors it will return the 1273 * last one. Done to always try to set as many samplers 1274 * as possible. 1275 */ 1276 void 1277 cso_set_samplers(struct cso_context *ctx, 1278 enum pipe_shader_type shader_stage, 1279 unsigned nr, 1280 const struct pipe_sampler_state **templates) 1281 { 1282 for (unsigned i = 0; i < nr; i++) 1283 cso_single_sampler(ctx, shader_stage, i, templates[i]); 1284 1285 cso_single_sampler_done(ctx, shader_stage); 1286 } 1287 1288 static void 1289 cso_save_fragment_samplers(struct cso_context *ctx) 1290 { 1291 struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT]; 1292 struct sampler_info *saved = &ctx->fragment_samplers_saved; 1293 1294 memcpy(saved->cso_samplers, info->cso_samplers, 1295 sizeof(info->cso_samplers)); 1296 memcpy(saved->samplers, info->samplers, sizeof(info->samplers)); 1297 } 1298 1299 1300 static void 1301 cso_restore_fragment_samplers(struct cso_context *ctx) 1302 { 1303 struct sampler_info *info = &ctx->samplers[PIPE_SHADER_FRAGMENT]; 1304 struct sampler_info *saved = &ctx->fragment_samplers_saved; 1305 1306 memcpy(info->cso_samplers, saved->cso_samplers, 1307 sizeof(info->cso_samplers)); 1308 memcpy(info->samplers, saved->samplers, sizeof(info->samplers)); 1309 1310 for (int i = PIPE_MAX_SAMPLERS - 1; i >= 0; i--) { 1311 if (info->samplers[i]) { 1312 ctx->max_sampler_seen = i; 1313 break; 1314 } 1315 } 1316 1317 cso_single_sampler_done(ctx, PIPE_SHADER_FRAGMENT); 1318 } 1319 1320 1321 void 1322 cso_set_sampler_views(struct cso_context *ctx, 1323 enum pipe_shader_type shader_stage, 1324 unsigned count, 1325 struct pipe_sampler_view **views) 1326 { 1327 if (shader_stage == PIPE_SHADER_FRAGMENT) { 1328 unsigned i; 1329 boolean any_change = FALSE; 1330 1331 /* reference new views */ 1332 for (i = 0; i < count; i++) { 1333 any_change |= ctx->fragment_views[i] != views[i]; 1334 pipe_sampler_view_reference(&ctx->fragment_views[i], views[i]); 1335 } 1336 /* unref extra old views, if any */ 1337 for (; i < ctx->nr_fragment_views; i++) { 1338 any_change |= ctx->fragment_views[i] != NULL; 1339 pipe_sampler_view_reference(&ctx->fragment_views[i], NULL); 1340 } 1341 1342 /* bind the new sampler views */ 1343 if (any_change) { 1344 ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0, 1345 MAX2(ctx->nr_fragment_views, count), 1346 ctx->fragment_views); 1347 } 1348 1349 ctx->nr_fragment_views = count; 1350 } 1351 else 1352 ctx->pipe->set_sampler_views(ctx->pipe, shader_stage, 0, count, views); 1353 } 1354 1355 1356 static void 1357 cso_save_fragment_sampler_views(struct cso_context *ctx) 1358 { 1359 unsigned i; 1360 1361 ctx->nr_fragment_views_saved = ctx->nr_fragment_views; 1362 1363 for (i = 0; i < ctx->nr_fragment_views; i++) { 1364 assert(!ctx->fragment_views_saved[i]); 1365 pipe_sampler_view_reference(&ctx->fragment_views_saved[i], 1366 ctx->fragment_views[i]); 1367 } 1368 } 1369 1370 1371 static void 1372 cso_restore_fragment_sampler_views(struct cso_context *ctx) 1373 { 1374 unsigned i, nr_saved = ctx->nr_fragment_views_saved; 1375 unsigned num; 1376 1377 for (i = 0; i < nr_saved; i++) { 1378 pipe_sampler_view_reference(&ctx->fragment_views[i], NULL); 1379 /* move the reference from one pointer to another */ 1380 ctx->fragment_views[i] = ctx->fragment_views_saved[i]; 1381 ctx->fragment_views_saved[i] = NULL; 1382 } 1383 for (; i < ctx->nr_fragment_views; i++) { 1384 pipe_sampler_view_reference(&ctx->fragment_views[i], NULL); 1385 } 1386 1387 num = MAX2(ctx->nr_fragment_views, nr_saved); 1388 1389 /* bind the old/saved sampler views */ 1390 ctx->pipe->set_sampler_views(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, num, 1391 ctx->fragment_views); 1392 1393 ctx->nr_fragment_views = nr_saved; 1394 ctx->nr_fragment_views_saved = 0; 1395 } 1396 1397 1398 void 1399 cso_set_shader_images(struct cso_context *ctx, 1400 enum pipe_shader_type shader_stage, 1401 unsigned start, unsigned count, 1402 struct pipe_image_view *images) 1403 { 1404 if (shader_stage == PIPE_SHADER_FRAGMENT && start == 0 && count >= 1) { 1405 util_copy_image_view(&ctx->fragment_image0_current, &images[0]); 1406 } 1407 1408 ctx->pipe->set_shader_images(ctx->pipe, shader_stage, start, count, images); 1409 } 1410 1411 1412 static void 1413 cso_save_fragment_image0(struct cso_context *ctx) 1414 { 1415 util_copy_image_view(&ctx->fragment_image0_saved, 1416 &ctx->fragment_image0_current); 1417 } 1418 1419 1420 static void 1421 cso_restore_fragment_image0(struct cso_context *ctx) 1422 { 1423 cso_set_shader_images(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 1424 &ctx->fragment_image0_saved); 1425 } 1426 1427 1428 void 1429 cso_set_stream_outputs(struct cso_context *ctx, 1430 unsigned num_targets, 1431 struct pipe_stream_output_target **targets, 1432 const unsigned *offsets) 1433 { 1434 struct pipe_context *pipe = ctx->pipe; 1435 uint i; 1436 1437 if (!ctx->has_streamout) { 1438 assert(num_targets == 0); 1439 return; 1440 } 1441 1442 if (ctx->nr_so_targets == 0 && num_targets == 0) { 1443 /* Nothing to do. */ 1444 return; 1445 } 1446 1447 /* reference new targets */ 1448 for (i = 0; i < num_targets; i++) { 1449 pipe_so_target_reference(&ctx->so_targets[i], targets[i]); 1450 } 1451 /* unref extra old targets, if any */ 1452 for (; i < ctx->nr_so_targets; i++) { 1453 pipe_so_target_reference(&ctx->so_targets[i], NULL); 1454 } 1455 1456 pipe->set_stream_output_targets(pipe, num_targets, targets, 1457 offsets); 1458 ctx->nr_so_targets = num_targets; 1459 } 1460 1461 static void 1462 cso_save_stream_outputs(struct cso_context *ctx) 1463 { 1464 uint i; 1465 1466 if (!ctx->has_streamout) { 1467 return; 1468 } 1469 1470 ctx->nr_so_targets_saved = ctx->nr_so_targets; 1471 1472 for (i = 0; i < ctx->nr_so_targets; i++) { 1473 assert(!ctx->so_targets_saved[i]); 1474 pipe_so_target_reference(&ctx->so_targets_saved[i], ctx->so_targets[i]); 1475 } 1476 } 1477 1478 static void 1479 cso_restore_stream_outputs(struct cso_context *ctx) 1480 { 1481 struct pipe_context *pipe = ctx->pipe; 1482 uint i; 1483 unsigned offset[PIPE_MAX_SO_BUFFERS]; 1484 1485 if (!ctx->has_streamout) { 1486 return; 1487 } 1488 1489 if (ctx->nr_so_targets == 0 && ctx->nr_so_targets_saved == 0) { 1490 /* Nothing to do. */ 1491 return; 1492 } 1493 1494 assert(ctx->nr_so_targets_saved <= PIPE_MAX_SO_BUFFERS); 1495 for (i = 0; i < ctx->nr_so_targets_saved; i++) { 1496 pipe_so_target_reference(&ctx->so_targets[i], NULL); 1497 /* move the reference from one pointer to another */ 1498 ctx->so_targets[i] = ctx->so_targets_saved[i]; 1499 ctx->so_targets_saved[i] = NULL; 1500 /* -1 means append */ 1501 offset[i] = (unsigned)-1; 1502 } 1503 for (; i < ctx->nr_so_targets; i++) { 1504 pipe_so_target_reference(&ctx->so_targets[i], NULL); 1505 } 1506 1507 pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved, 1508 ctx->so_targets, offset); 1509 1510 ctx->nr_so_targets = ctx->nr_so_targets_saved; 1511 ctx->nr_so_targets_saved = 0; 1512 } 1513 1514 /* constant buffers */ 1515 1516 void 1517 cso_set_constant_buffer(struct cso_context *cso, 1518 enum pipe_shader_type shader_stage, 1519 unsigned index, struct pipe_constant_buffer *cb) 1520 { 1521 struct pipe_context *pipe = cso->pipe; 1522 1523 pipe->set_constant_buffer(pipe, shader_stage, index, cb); 1524 1525 if (index == 0) { 1526 util_copy_constant_buffer(&cso->aux_constbuf_current[shader_stage], cb); 1527 } 1528 } 1529 1530 void 1531 cso_set_constant_buffer_resource(struct cso_context *cso, 1532 enum pipe_shader_type shader_stage, 1533 unsigned index, 1534 struct pipe_resource *buffer) 1535 { 1536 if (buffer) { 1537 struct pipe_constant_buffer cb; 1538 cb.buffer = buffer; 1539 cb.buffer_offset = 0; 1540 cb.buffer_size = buffer->width0; 1541 cb.user_buffer = NULL; 1542 cso_set_constant_buffer(cso, shader_stage, index, &cb); 1543 } else { 1544 cso_set_constant_buffer(cso, shader_stage, index, NULL); 1545 } 1546 } 1547 1548 void 1549 cso_save_constant_buffer_slot0(struct cso_context *cso, 1550 enum pipe_shader_type shader_stage) 1551 { 1552 util_copy_constant_buffer(&cso->aux_constbuf_saved[shader_stage], 1553 &cso->aux_constbuf_current[shader_stage]); 1554 } 1555 1556 void 1557 cso_restore_constant_buffer_slot0(struct cso_context *cso, 1558 enum pipe_shader_type shader_stage) 1559 { 1560 cso_set_constant_buffer(cso, shader_stage, 0, 1561 &cso->aux_constbuf_saved[shader_stage]); 1562 pipe_resource_reference(&cso->aux_constbuf_saved[shader_stage].buffer, 1563 NULL); 1564 } 1565 1566 1567 /** 1568 * Save all the CSO state items specified by the state_mask bitmask 1569 * of CSO_BIT_x flags. 1570 */ 1571 void 1572 cso_save_state(struct cso_context *cso, unsigned state_mask) 1573 { 1574 assert(cso->saved_state == 0); 1575 1576 cso->saved_state = state_mask; 1577 1578 if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT) 1579 cso_save_aux_vertex_buffer_slot(cso); 1580 if (state_mask & CSO_BIT_BLEND) 1581 cso_save_blend(cso); 1582 if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA) 1583 cso_save_depth_stencil_alpha(cso); 1584 if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS) 1585 cso_save_fragment_samplers(cso); 1586 if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS) 1587 cso_save_fragment_sampler_views(cso); 1588 if (state_mask & CSO_BIT_FRAGMENT_SHADER) 1589 cso_save_fragment_shader(cso); 1590 if (state_mask & CSO_BIT_FRAMEBUFFER) 1591 cso_save_framebuffer(cso); 1592 if (state_mask & CSO_BIT_GEOMETRY_SHADER) 1593 cso_save_geometry_shader(cso); 1594 if (state_mask & CSO_BIT_MIN_SAMPLES) 1595 cso_save_min_samples(cso); 1596 if (state_mask & CSO_BIT_RASTERIZER) 1597 cso_save_rasterizer(cso); 1598 if (state_mask & CSO_BIT_RENDER_CONDITION) 1599 cso_save_render_condition(cso); 1600 if (state_mask & CSO_BIT_SAMPLE_MASK) 1601 cso_save_sample_mask(cso); 1602 if (state_mask & CSO_BIT_STENCIL_REF) 1603 cso_save_stencil_ref(cso); 1604 if (state_mask & CSO_BIT_STREAM_OUTPUTS) 1605 cso_save_stream_outputs(cso); 1606 if (state_mask & CSO_BIT_TESSCTRL_SHADER) 1607 cso_save_tessctrl_shader(cso); 1608 if (state_mask & CSO_BIT_TESSEVAL_SHADER) 1609 cso_save_tesseval_shader(cso); 1610 if (state_mask & CSO_BIT_VERTEX_ELEMENTS) 1611 cso_save_vertex_elements(cso); 1612 if (state_mask & CSO_BIT_VERTEX_SHADER) 1613 cso_save_vertex_shader(cso); 1614 if (state_mask & CSO_BIT_VIEWPORT) 1615 cso_save_viewport(cso); 1616 if (state_mask & CSO_BIT_PAUSE_QUERIES) 1617 cso->pipe->set_active_query_state(cso->pipe, false); 1618 if (state_mask & CSO_BIT_FRAGMENT_IMAGE0) 1619 cso_save_fragment_image0(cso); 1620 } 1621 1622 1623 /** 1624 * Restore the state which was saved by cso_save_state(). 1625 */ 1626 void 1627 cso_restore_state(struct cso_context *cso) 1628 { 1629 unsigned state_mask = cso->saved_state; 1630 1631 assert(state_mask); 1632 1633 if (state_mask & CSO_BIT_AUX_VERTEX_BUFFER_SLOT) 1634 cso_restore_aux_vertex_buffer_slot(cso); 1635 if (state_mask & CSO_BIT_BLEND) 1636 cso_restore_blend(cso); 1637 if (state_mask & CSO_BIT_DEPTH_STENCIL_ALPHA) 1638 cso_restore_depth_stencil_alpha(cso); 1639 if (state_mask & CSO_BIT_FRAGMENT_SAMPLERS) 1640 cso_restore_fragment_samplers(cso); 1641 if (state_mask & CSO_BIT_FRAGMENT_SAMPLER_VIEWS) 1642 cso_restore_fragment_sampler_views(cso); 1643 if (state_mask & CSO_BIT_FRAGMENT_SHADER) 1644 cso_restore_fragment_shader(cso); 1645 if (state_mask & CSO_BIT_FRAMEBUFFER) 1646 cso_restore_framebuffer(cso); 1647 if (state_mask & CSO_BIT_GEOMETRY_SHADER) 1648 cso_restore_geometry_shader(cso); 1649 if (state_mask & CSO_BIT_MIN_SAMPLES) 1650 cso_restore_min_samples(cso); 1651 if (state_mask & CSO_BIT_RASTERIZER) 1652 cso_restore_rasterizer(cso); 1653 if (state_mask & CSO_BIT_RENDER_CONDITION) 1654 cso_restore_render_condition(cso); 1655 if (state_mask & CSO_BIT_SAMPLE_MASK) 1656 cso_restore_sample_mask(cso); 1657 if (state_mask & CSO_BIT_STENCIL_REF) 1658 cso_restore_stencil_ref(cso); 1659 if (state_mask & CSO_BIT_STREAM_OUTPUTS) 1660 cso_restore_stream_outputs(cso); 1661 if (state_mask & CSO_BIT_TESSCTRL_SHADER) 1662 cso_restore_tessctrl_shader(cso); 1663 if (state_mask & CSO_BIT_TESSEVAL_SHADER) 1664 cso_restore_tesseval_shader(cso); 1665 if (state_mask & CSO_BIT_VERTEX_ELEMENTS) 1666 cso_restore_vertex_elements(cso); 1667 if (state_mask & CSO_BIT_VERTEX_SHADER) 1668 cso_restore_vertex_shader(cso); 1669 if (state_mask & CSO_BIT_VIEWPORT) 1670 cso_restore_viewport(cso); 1671 if (state_mask & CSO_BIT_PAUSE_QUERIES) 1672 cso->pipe->set_active_query_state(cso->pipe, true); 1673 if (state_mask & CSO_BIT_FRAGMENT_IMAGE0) 1674 cso_restore_fragment_image0(cso); 1675 1676 cso->saved_state = 0; 1677 } 1678 1679 1680 1681 /* drawing */ 1682 1683 void 1684 cso_draw_vbo(struct cso_context *cso, 1685 const struct pipe_draw_info *info) 1686 { 1687 struct u_vbuf *vbuf = cso->vbuf; 1688 1689 if (vbuf) { 1690 u_vbuf_draw_vbo(vbuf, info); 1691 } else { 1692 struct pipe_context *pipe = cso->pipe; 1693 pipe->draw_vbo(pipe, info); 1694 } 1695 } 1696 1697 void 1698 cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count) 1699 { 1700 struct pipe_draw_info info; 1701 1702 util_draw_init_info(&info); 1703 1704 info.mode = mode; 1705 info.start = start; 1706 info.count = count; 1707 info.min_index = start; 1708 info.max_index = start + count - 1; 1709 1710 cso_draw_vbo(cso, &info); 1711 } 1712 1713 void 1714 cso_draw_arrays_instanced(struct cso_context *cso, uint mode, 1715 uint start, uint count, 1716 uint start_instance, uint instance_count) 1717 { 1718 struct pipe_draw_info info; 1719 1720 util_draw_init_info(&info); 1721 1722 info.mode = mode; 1723 info.start = start; 1724 info.count = count; 1725 info.min_index = start; 1726 info.max_index = start + count - 1; 1727 info.start_instance = start_instance; 1728 info.instance_count = instance_count; 1729 1730 cso_draw_vbo(cso, &info); 1731 } 1732