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