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