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