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