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