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