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