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