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