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