1d71a87319eefc27d3d5c55aa1a01a45764f03d6
[mesa.git] / src / gallium / drivers / llvmpipe / lp_setup.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /**
29 * Tiling engine.
30 *
31 * Builds per-tile display lists and executes them on calls to
32 * lp_setup_flush().
33 */
34
35 #include <limits.h>
36
37 #include "pipe/p_defines.h"
38 #include "util/u_framebuffer.h"
39 #include "util/u_inlines.h"
40 #include "util/u_memory.h"
41 #include "util/u_pack_color.h"
42 #include "draw/draw_pipe.h"
43 #include "lp_context.h"
44 #include "lp_memory.h"
45 #include "lp_scene.h"
46 #include "lp_texture.h"
47 #include "lp_debug.h"
48 #include "lp_fence.h"
49 #include "lp_query.h"
50 #include "lp_rast.h"
51 #include "lp_setup_context.h"
52 #include "lp_screen.h"
53 #include "lp_state.h"
54 #include "state_tracker/sw_winsys.h"
55
56 #include "draw/draw_context.h"
57 #include "draw/draw_vbuf.h"
58
59
60 static boolean set_scene_state( struct lp_setup_context *, enum setup_state,
61 const char *reason);
62 static boolean try_update_scene_state( struct lp_setup_context *setup );
63
64
65 static void
66 lp_setup_get_empty_scene(struct lp_setup_context *setup)
67 {
68 assert(setup->scene == NULL);
69
70 setup->scene_idx++;
71 setup->scene_idx %= Elements(setup->scenes);
72
73 setup->scene = setup->scenes[setup->scene_idx];
74
75 if (setup->scene->fence) {
76 if (LP_DEBUG & DEBUG_SETUP)
77 debug_printf("%s: wait for scene %d\n",
78 __FUNCTION__, setup->scene->fence->id);
79
80 lp_fence_wait(setup->scene->fence);
81 }
82
83 lp_scene_begin_binning(setup->scene, &setup->fb);
84
85 }
86
87
88 static void
89 first_triangle( struct lp_setup_context *setup,
90 const float (*v0)[4],
91 const float (*v1)[4],
92 const float (*v2)[4])
93 {
94 assert(setup->state == SETUP_ACTIVE);
95 lp_setup_choose_triangle( setup );
96 setup->triangle( setup, v0, v1, v2 );
97 }
98
99 static void
100 first_line( struct lp_setup_context *setup,
101 const float (*v0)[4],
102 const float (*v1)[4])
103 {
104 assert(setup->state == SETUP_ACTIVE);
105 lp_setup_choose_line( setup );
106 setup->line( setup, v0, v1 );
107 }
108
109 static void
110 first_point( struct lp_setup_context *setup,
111 const float (*v0)[4])
112 {
113 assert(setup->state == SETUP_ACTIVE);
114 lp_setup_choose_point( setup );
115 setup->point( setup, v0 );
116 }
117
118 void lp_setup_reset( struct lp_setup_context *setup )
119 {
120 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
121
122 /* Reset derived state */
123 setup->constants.stored_size = 0;
124 setup->constants.stored_data = NULL;
125 setup->fs.stored = NULL;
126 setup->dirty = ~0;
127
128 /* no current bin */
129 setup->scene = NULL;
130
131 /* Reset some state:
132 */
133 memset(&setup->clear, 0, sizeof setup->clear);
134
135 /* Have an explicit "start-binning" call and get rid of this
136 * pointer twiddling?
137 */
138 setup->line = first_line;
139 setup->point = first_point;
140 setup->triangle = first_triangle;
141 }
142
143
144 /** Rasterize all scene's bins */
145 static void
146 lp_setup_rasterize_scene( struct lp_setup_context *setup )
147 {
148 struct lp_scene *scene = setup->scene;
149 struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);
150
151 lp_scene_end_binning(scene);
152
153 lp_fence_reference(&setup->last_fence, scene->fence);
154
155 if (setup->last_fence)
156 setup->last_fence->issued = TRUE;
157
158 pipe_mutex_lock(screen->rast_mutex);
159 lp_rast_queue_scene(screen->rast, scene);
160 lp_rast_finish(screen->rast);
161 pipe_mutex_unlock(screen->rast_mutex);
162
163 lp_scene_end_rasterization(setup->scene);
164 lp_setup_reset( setup );
165
166 LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
167 }
168
169
170
171 static boolean
172 begin_binning( struct lp_setup_context *setup )
173 {
174 struct lp_scene *scene = setup->scene;
175 boolean need_zsload = FALSE;
176 boolean ok;
177 unsigned i, j;
178
179 assert(scene);
180 assert(scene->fence == NULL);
181
182 /* Always create a fence:
183 */
184 scene->fence = lp_fence_create(MAX2(1, setup->num_threads));
185 if (!scene->fence)
186 return FALSE;
187
188 /* Initialize the bin flags and x/y coords:
189 */
190 for (i = 0; i < scene->tiles_x; i++) {
191 for (j = 0; j < scene->tiles_y; j++) {
192 scene->tile[i][j].x = i;
193 scene->tile[i][j].y = j;
194 }
195 }
196
197 ok = try_update_scene_state(setup);
198 if (!ok)
199 return FALSE;
200
201 if (setup->fb.zsbuf &&
202 ((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
203 util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
204 need_zsload = TRUE;
205
206 LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
207 (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
208 need_zsload ? "clear": "load");
209
210 if (setup->fb.nr_cbufs) {
211 if (setup->clear.flags & PIPE_CLEAR_COLOR) {
212 ok = lp_scene_bin_everywhere( scene,
213 LP_RAST_OP_CLEAR_COLOR,
214 setup->clear.color );
215 if (!ok)
216 return FALSE;
217 }
218 }
219
220 if (setup->fb.zsbuf) {
221 if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
222 if (!need_zsload)
223 scene->has_depthstencil_clear = TRUE;
224
225 ok = lp_scene_bin_everywhere( scene,
226 LP_RAST_OP_CLEAR_ZSTENCIL,
227 lp_rast_arg_clearzs(
228 setup->clear.zsvalue,
229 setup->clear.zsmask));
230 if (!ok)
231 return FALSE;
232 }
233 }
234
235 for (i = 0; i < PIPE_QUERY_TYPES; ++i) {
236 if (setup->active_query[i]) {
237 ok = lp_scene_bin_everywhere( scene,
238 LP_RAST_OP_BEGIN_QUERY,
239 lp_rast_arg_query(setup->active_query[i]) );
240 if (!ok)
241 return FALSE;
242 }
243 }
244
245 setup->clear.flags = 0;
246 setup->clear.zsmask = 0;
247 setup->clear.zsvalue = 0;
248
249 LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__);
250 return TRUE;
251 }
252
253
254 /* This basically bins and then flushes any outstanding full-screen
255 * clears.
256 *
257 * TODO: fast path for fullscreen clears and no triangles.
258 */
259 static boolean
260 execute_clears( struct lp_setup_context *setup )
261 {
262 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
263
264 return begin_binning( setup );
265 }
266
267 const char *states[] = {
268 "FLUSHED",
269 "CLEARED",
270 "ACTIVE "
271 };
272
273
274 static boolean
275 set_scene_state( struct lp_setup_context *setup,
276 enum setup_state new_state,
277 const char *reason)
278 {
279 unsigned old_state = setup->state;
280
281 if (old_state == new_state)
282 return TRUE;
283
284 if (LP_DEBUG & DEBUG_SCENE) {
285 debug_printf("%s old %s new %s%s%s\n",
286 __FUNCTION__,
287 states[old_state],
288 states[new_state],
289 (new_state == SETUP_FLUSHED) ? ": " : "",
290 (new_state == SETUP_FLUSHED) ? reason : "");
291
292 if (new_state == SETUP_FLUSHED && setup->scene)
293 lp_debug_draw_bins_by_cmd_length(setup->scene);
294 }
295
296 /* wait for a free/empty scene
297 */
298 if (old_state == SETUP_FLUSHED)
299 lp_setup_get_empty_scene(setup);
300
301 switch (new_state) {
302 case SETUP_CLEARED:
303 break;
304
305 case SETUP_ACTIVE:
306 if (!begin_binning( setup ))
307 goto fail;
308 break;
309
310 case SETUP_FLUSHED:
311 if (old_state == SETUP_CLEARED)
312 if (!execute_clears( setup ))
313 goto fail;
314
315 lp_setup_rasterize_scene( setup );
316 assert(setup->scene == NULL);
317 break;
318
319 default:
320 assert(0 && "invalid setup state mode");
321 goto fail;
322 }
323
324 setup->state = new_state;
325 return TRUE;
326
327 fail:
328 if (setup->scene) {
329 lp_scene_end_rasterization(setup->scene);
330 setup->scene = NULL;
331 }
332
333 setup->state = SETUP_FLUSHED;
334 lp_setup_reset( setup );
335 return FALSE;
336 }
337
338
339 void
340 lp_setup_flush( struct lp_setup_context *setup,
341 struct pipe_fence_handle **fence,
342 const char *reason)
343 {
344 set_scene_state( setup, SETUP_FLUSHED, reason );
345
346 if (fence) {
347 lp_fence_reference((struct lp_fence **)fence, setup->last_fence);
348 }
349 }
350
351
352 void
353 lp_setup_bind_framebuffer( struct lp_setup_context *setup,
354 const struct pipe_framebuffer_state *fb )
355 {
356 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
357
358 /* Flush any old scene.
359 */
360 set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
361
362 /*
363 * Ensure the old scene is not reused.
364 */
365 assert(!setup->scene);
366
367 /* Set new state. This will be picked up later when we next need a
368 * scene.
369 */
370 util_copy_framebuffer_state(&setup->fb, fb);
371 setup->framebuffer.x0 = 0;
372 setup->framebuffer.y0 = 0;
373 setup->framebuffer.x1 = fb->width-1;
374 setup->framebuffer.y1 = fb->height-1;
375 setup->dirty |= LP_SETUP_NEW_SCISSOR;
376 }
377
378
379 static boolean
380 lp_setup_try_clear( struct lp_setup_context *setup,
381 const float *color,
382 double depth,
383 unsigned stencil,
384 unsigned flags )
385 {
386 uint32_t zsmask = 0;
387 uint32_t zsvalue = 0;
388 union lp_rast_cmd_arg color_arg;
389 unsigned i;
390
391 LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
392
393 if (flags & PIPE_CLEAR_COLOR) {
394 for (i = 0; i < 4; i++)
395 color_arg.clear_color[i] = color[i];
396 }
397
398 if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
399 uint32_t zmask = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0;
400 uint32_t smask = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0;
401
402 zsvalue = util_pack_z_stencil(setup->fb.zsbuf->format,
403 depth,
404 stencil);
405
406
407 zsmask = util_pack_mask_z_stencil(setup->fb.zsbuf->format,
408 zmask,
409 smask);
410
411 zsvalue &= zsmask;
412 }
413
414 if (setup->state == SETUP_ACTIVE) {
415 struct lp_scene *scene = setup->scene;
416
417 /* Add the clear to existing scene. In the unusual case where
418 * both color and depth-stencil are being cleared when there's
419 * already been some rendering, we could discard the currently
420 * binned scene and start again, but I don't see that as being
421 * a common usage.
422 */
423 if (flags & PIPE_CLEAR_COLOR) {
424 if (!lp_scene_bin_everywhere( scene,
425 LP_RAST_OP_CLEAR_COLOR,
426 color_arg ))
427 return FALSE;
428 }
429
430 if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
431 if (!lp_scene_bin_everywhere( scene,
432 LP_RAST_OP_CLEAR_ZSTENCIL,
433 lp_rast_arg_clearzs(zsvalue, zsmask) ))
434 return FALSE;
435 }
436 }
437 else {
438 /* Put ourselves into the 'pre-clear' state, specifically to try
439 * and accumulate multiple clears to color and depth_stencil
440 * buffers which the app or state-tracker might issue
441 * separately.
442 */
443 set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ );
444
445 setup->clear.flags |= flags;
446
447 if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
448 setup->clear.zsmask |= zsmask;
449 setup->clear.zsvalue =
450 (setup->clear.zsvalue & ~zsmask) | (zsvalue & zsmask);
451 }
452
453 if (flags & PIPE_CLEAR_COLOR) {
454 memcpy(setup->clear.color.clear_color,
455 &color_arg,
456 sizeof setup->clear.color.clear_color);
457 }
458 }
459
460 return TRUE;
461 }
462
463 void
464 lp_setup_clear( struct lp_setup_context *setup,
465 const float *color,
466 double depth,
467 unsigned stencil,
468 unsigned flags )
469 {
470 if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) {
471 lp_setup_flush(setup, NULL, __FUNCTION__);
472
473 if (!lp_setup_try_clear( setup, color, depth, stencil, flags ))
474 assert(0);
475 }
476 }
477
478
479
480
481
482 void
483 lp_setup_set_triangle_state( struct lp_setup_context *setup,
484 unsigned cull_mode,
485 boolean ccw_is_frontface,
486 boolean scissor,
487 boolean gl_rasterization_rules)
488 {
489 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
490
491 setup->ccw_is_frontface = ccw_is_frontface;
492 setup->cullmode = cull_mode;
493 setup->triangle = first_triangle;
494 setup->pixel_offset = gl_rasterization_rules ? 0.5f : 0.0f;
495
496 if (setup->scissor_test != scissor) {
497 setup->dirty |= LP_SETUP_NEW_SCISSOR;
498 setup->scissor_test = scissor;
499 }
500 }
501
502 void
503 lp_setup_set_line_state( struct lp_setup_context *setup,
504 float line_width)
505 {
506 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
507
508 setup->line_width = line_width;
509 }
510
511 void
512 lp_setup_set_point_state( struct lp_setup_context *setup,
513 float point_size,
514 boolean point_size_per_vertex,
515 uint sprite_coord_enable,
516 uint sprite_coord_origin)
517 {
518 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
519
520 setup->point_size = point_size;
521 setup->sprite_coord_enable = sprite_coord_enable;
522 setup->sprite_coord_origin = sprite_coord_origin;
523 setup->point_size_per_vertex = point_size_per_vertex;
524 }
525
526 void
527 lp_setup_set_setup_variant( struct lp_setup_context *setup,
528 const struct lp_setup_variant *variant)
529 {
530 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
531
532 setup->setup.variant = variant;
533 }
534
535 void
536 lp_setup_set_fs_variant( struct lp_setup_context *setup,
537 struct lp_fragment_shader_variant *variant)
538 {
539 LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__,
540 variant);
541 /* FIXME: reference count */
542
543 setup->fs.current.variant = variant;
544 setup->dirty |= LP_SETUP_NEW_FS;
545 }
546
547 void
548 lp_setup_set_fs_constants(struct lp_setup_context *setup,
549 struct pipe_resource *buffer)
550 {
551 LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer);
552
553 pipe_resource_reference(&setup->constants.current, buffer);
554
555 setup->dirty |= LP_SETUP_NEW_CONSTANTS;
556 }
557
558
559 void
560 lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
561 float alpha_ref_value )
562 {
563 LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value);
564
565 if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) {
566 setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value;
567 setup->dirty |= LP_SETUP_NEW_FS;
568 }
569 }
570
571 void
572 lp_setup_set_stencil_ref_values( struct lp_setup_context *setup,
573 const ubyte refs[2] )
574 {
575 LP_DBG(DEBUG_SETUP, "%s %d %d\n", __FUNCTION__, refs[0], refs[1]);
576
577 if (setup->fs.current.jit_context.stencil_ref_front != refs[0] ||
578 setup->fs.current.jit_context.stencil_ref_back != refs[1]) {
579 setup->fs.current.jit_context.stencil_ref_front = refs[0];
580 setup->fs.current.jit_context.stencil_ref_back = refs[1];
581 setup->dirty |= LP_SETUP_NEW_FS;
582 }
583 }
584
585 void
586 lp_setup_set_blend_color( struct lp_setup_context *setup,
587 const struct pipe_blend_color *blend_color )
588 {
589 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
590
591 assert(blend_color);
592
593 if(memcmp(&setup->blend_color.current, blend_color, sizeof *blend_color) != 0) {
594 memcpy(&setup->blend_color.current, blend_color, sizeof *blend_color);
595 setup->dirty |= LP_SETUP_NEW_BLEND_COLOR;
596 }
597 }
598
599
600 void
601 lp_setup_set_scissor( struct lp_setup_context *setup,
602 const struct pipe_scissor_state *scissor )
603 {
604 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
605
606 assert(scissor);
607
608 setup->scissor.x0 = scissor->minx;
609 setup->scissor.x1 = scissor->maxx-1;
610 setup->scissor.y0 = scissor->miny;
611 setup->scissor.y1 = scissor->maxy-1;
612 setup->dirty |= LP_SETUP_NEW_SCISSOR;
613 }
614
615
616 void
617 lp_setup_set_flatshade_first( struct lp_setup_context *setup,
618 boolean flatshade_first )
619 {
620 setup->flatshade_first = flatshade_first;
621 }
622
623
624 void
625 lp_setup_set_vertex_info( struct lp_setup_context *setup,
626 struct vertex_info *vertex_info )
627 {
628 /* XXX: just silently holding onto the pointer:
629 */
630 setup->vertex_info = vertex_info;
631 }
632
633
634 /**
635 * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
636 */
637 void
638 lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
639 unsigned num,
640 struct pipe_sampler_view **views)
641 {
642 unsigned i;
643
644 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
645
646 assert(num <= PIPE_MAX_SAMPLERS);
647
648 for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
649 struct pipe_sampler_view *view = i < num ? views[i] : NULL;
650
651 if (view) {
652 struct pipe_resource *tex = view->texture;
653 struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
654 struct lp_jit_texture *jit_tex;
655 jit_tex = &setup->fs.current.jit_context.textures[i];
656 jit_tex->width = tex->width0;
657 jit_tex->height = tex->height0;
658 jit_tex->first_level = view->u.tex.first_level;
659 jit_tex->last_level = tex->last_level;
660
661 if (tex->target == PIPE_TEXTURE_3D) {
662 jit_tex->depth = tex->depth0;
663 }
664 else {
665 jit_tex->depth = tex->array_size;
666 }
667
668 /* We're referencing the texture's internal data, so save a
669 * reference to it.
670 */
671 pipe_resource_reference(&setup->fs.current_tex[i], tex);
672
673 if (!lp_tex->dt) {
674 /* regular texture - setup array of mipmap level offsets */
675 void *mip_ptr;
676 int j;
677 /*
678 * XXX this is messed up we don't want to accidentally trigger
679 * tiled->linear conversion for levels we don't need.
680 * So ask for first_level data (which will allocate all levels)
681 * then if successful get base ptr.
682 */
683 mip_ptr = llvmpipe_get_texture_image_all(lp_tex, view->u.tex.first_level,
684 LP_TEX_USAGE_READ,
685 LP_TEX_LAYOUT_LINEAR);
686 if ((LP_PERF & PERF_TEX_MEM) || !mip_ptr) {
687 /* out of memory - use dummy tile memory */
688 jit_tex->base = lp_dummy_tile;
689 jit_tex->width = TILE_SIZE/8;
690 jit_tex->height = TILE_SIZE/8;
691 jit_tex->depth = 1;
692 jit_tex->first_level = 0;
693 jit_tex->last_level = 0;
694 }
695 else {
696 jit_tex->base = lp_tex->linear_img.data;
697 }
698 for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
699 mip_ptr = llvmpipe_get_texture_image_all(lp_tex, j,
700 LP_TEX_USAGE_READ,
701 LP_TEX_LAYOUT_LINEAR);
702 jit_tex->mip_offsets[j] = (uint8_t *)mip_ptr - (uint8_t *)jit_tex->base;
703 /*
704 * could get mip offset directly but need call above to
705 * invoke tiled->linear conversion.
706 */
707 assert(lp_tex->linear_mip_offsets[j] == jit_tex->mip_offsets[j]);
708 jit_tex->row_stride[j] = lp_tex->row_stride[j];
709 jit_tex->img_stride[j] = lp_tex->img_stride[j];
710
711 if (jit_tex->base == lp_dummy_tile) {
712 /* out of memory - use dummy tile memory */
713 jit_tex->mip_offsets[j] = 0;
714 jit_tex->row_stride[j] = 0;
715 jit_tex->img_stride[j] = 0;
716 }
717 }
718 }
719 else {
720 /* display target texture/surface */
721 /*
722 * XXX: Where should this be unmapped?
723 */
724 struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
725 struct sw_winsys *winsys = screen->winsys;
726 jit_tex->base = winsys->displaytarget_map(winsys, lp_tex->dt,
727 PIPE_TRANSFER_READ);
728 jit_tex->row_stride[0] = lp_tex->row_stride[0];
729 jit_tex->img_stride[0] = lp_tex->img_stride[0];
730 jit_tex->mip_offsets[0] = 0;
731 assert(jit_tex->base);
732 }
733 }
734 }
735
736 setup->dirty |= LP_SETUP_NEW_FS;
737 }
738
739
740 /**
741 * Called during state validation when LP_NEW_SAMPLER is set.
742 */
743 void
744 lp_setup_set_fragment_sampler_state(struct lp_setup_context *setup,
745 unsigned num,
746 struct pipe_sampler_state **samplers)
747 {
748 unsigned i;
749
750 LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
751
752 assert(num <= PIPE_MAX_SAMPLERS);
753
754 for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
755 const struct pipe_sampler_state *sampler = i < num ? samplers[i] : NULL;
756
757 if (sampler) {
758 struct lp_jit_texture *jit_tex;
759 jit_tex = &setup->fs.current.jit_context.textures[i];
760
761 jit_tex->min_lod = sampler->min_lod;
762 jit_tex->max_lod = sampler->max_lod;
763 jit_tex->lod_bias = sampler->lod_bias;
764 COPY_4V(jit_tex->border_color, sampler->border_color.f);
765 }
766 }
767
768 setup->dirty |= LP_SETUP_NEW_FS;
769 }
770
771
772 /**
773 * Is the given texture referenced by any scene?
774 * Note: we have to check all scenes including any scenes currently
775 * being rendered and the current scene being built.
776 */
777 unsigned
778 lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
779 const struct pipe_resource *texture )
780 {
781 unsigned i;
782
783 /* check the render targets */
784 for (i = 0; i < setup->fb.nr_cbufs; i++) {
785 if (setup->fb.cbufs[i]->texture == texture)
786 return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
787 }
788 if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) {
789 return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
790 }
791
792 /* check textures referenced by the scene */
793 for (i = 0; i < Elements(setup->scenes); i++) {
794 if (lp_scene_is_resource_referenced(setup->scenes[i], texture)) {
795 return LP_REFERENCED_FOR_READ;
796 }
797 }
798
799 return LP_UNREFERENCED;
800 }
801
802
803 /**
804 * Called by vbuf code when we're about to draw something.
805 */
806 static boolean
807 try_update_scene_state( struct lp_setup_context *setup )
808 {
809 boolean new_scene = (setup->fs.stored == NULL);
810 struct lp_scene *scene = setup->scene;
811
812 assert(scene);
813
814 if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
815 uint8_t *stored;
816 float* fstored;
817 unsigned i, j;
818 unsigned size;
819
820 /* Alloc u8_blend_color (16 x i8) and f_blend_color (4 or 8 x f32) */
821 size = 4 * 16 * sizeof(uint8_t);
822 size += (LP_MAX_VECTOR_LENGTH / 4) * sizeof(float);
823 stored = lp_scene_alloc_aligned(scene, size, LP_MAX_VECTOR_LENGTH);
824
825 if (!stored) {
826 assert(!new_scene);
827 return FALSE;
828 }
829
830 /* Store floating point colour */
831 fstored = (float*)(stored + 4*16);
832 for (i = 0; i < (LP_MAX_VECTOR_LENGTH / 4); ++i) {
833 fstored[i] = setup->blend_color.current.color[i % 4];
834 }
835
836 /* smear each blend color component across 16 ubyte elements */
837 for (i = 0; i < 4; ++i) {
838 uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]);
839 for (j = 0; j < 16; ++j)
840 stored[i*16 + j] = c;
841 }
842
843 setup->blend_color.stored = stored;
844 setup->fs.current.jit_context.u8_blend_color = stored;
845 setup->fs.current.jit_context.f_blend_color = fstored;
846 setup->dirty |= LP_SETUP_NEW_FS;
847 }
848
849 if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
850 struct pipe_resource *buffer = setup->constants.current;
851
852 if(buffer) {
853 unsigned current_size = buffer->width0;
854 const void *current_data = llvmpipe_resource_data(buffer);
855
856 /* TODO: copy only the actually used constants? */
857
858 if(setup->constants.stored_size != current_size ||
859 !setup->constants.stored_data ||
860 memcmp(setup->constants.stored_data,
861 current_data,
862 current_size) != 0) {
863 void *stored;
864
865 stored = lp_scene_alloc(scene, current_size);
866 if (!stored) {
867 assert(!new_scene);
868 return FALSE;
869 }
870
871 memcpy(stored,
872 current_data,
873 current_size);
874 setup->constants.stored_size = current_size;
875 setup->constants.stored_data = stored;
876 }
877 }
878 else {
879 setup->constants.stored_size = 0;
880 setup->constants.stored_data = NULL;
881 }
882
883 setup->fs.current.jit_context.constants = setup->constants.stored_data;
884 setup->dirty |= LP_SETUP_NEW_FS;
885 }
886
887
888 if (setup->dirty & LP_SETUP_NEW_FS) {
889 if (!setup->fs.stored ||
890 memcmp(setup->fs.stored,
891 &setup->fs.current,
892 sizeof setup->fs.current) != 0)
893 {
894 struct lp_rast_state *stored;
895 uint i;
896
897 /* The fs state that's been stored in the scene is different from
898 * the new, current state. So allocate a new lp_rast_state object
899 * and append it to the bin's setup data buffer.
900 */
901 stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
902 if (!stored) {
903 assert(!new_scene);
904 return FALSE;
905 }
906
907 memcpy(stored,
908 &setup->fs.current,
909 sizeof setup->fs.current);
910 setup->fs.stored = stored;
911
912 /* The scene now references the textures in the rasterization
913 * state record. Note that now.
914 */
915 for (i = 0; i < Elements(setup->fs.current_tex); i++) {
916 if (setup->fs.current_tex[i]) {
917 if (!lp_scene_add_resource_reference(scene,
918 setup->fs.current_tex[i],
919 new_scene)) {
920 assert(!new_scene);
921 return FALSE;
922 }
923 }
924 }
925 }
926 }
927
928 if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
929 setup->draw_region = setup->framebuffer;
930 if (setup->scissor_test) {
931 u_rect_possible_intersection(&setup->scissor,
932 &setup->draw_region);
933 }
934 }
935
936 setup->dirty = 0;
937
938 assert(setup->fs.stored);
939 return TRUE;
940 }
941
942 boolean
943 lp_setup_update_state( struct lp_setup_context *setup,
944 boolean update_scene )
945 {
946 /* Some of the 'draw' pipeline stages may have changed some driver state.
947 * Make sure we've processed those state changes before anything else.
948 *
949 * XXX this is the only place where llvmpipe_context is used in the
950 * setup code. This may get refactored/changed...
951 */
952 {
953 struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
954 if (lp->dirty) {
955 llvmpipe_update_derived(lp);
956 }
957
958 if (lp->setup->dirty) {
959 llvmpipe_update_setup(lp);
960 }
961
962 assert(setup->setup.variant);
963
964 /* Will probably need to move this somewhere else, just need
965 * to know about vertex shader point size attribute.
966 */
967 setup->psize = lp->psize_slot;
968
969 assert(lp->dirty == 0);
970
971 assert(lp->setup_variant.key.size ==
972 setup->setup.variant->key.size);
973
974 assert(memcmp(&lp->setup_variant.key,
975 &setup->setup.variant->key,
976 setup->setup.variant->key.size) == 0);
977 }
978
979 if (update_scene && setup->state != SETUP_ACTIVE) {
980 if (!set_scene_state( setup, SETUP_ACTIVE, __FUNCTION__ ))
981 return FALSE;
982 }
983
984 /* Only call into update_scene_state() if we already have a
985 * scene:
986 */
987 if (update_scene && setup->scene) {
988 assert(setup->state == SETUP_ACTIVE);
989
990 if (try_update_scene_state(setup))
991 return TRUE;
992
993 /* Update failed, try to restart the scene.
994 *
995 * Cannot call lp_setup_flush_and_restart() directly here
996 * because of potential recursion.
997 */
998 if (!set_scene_state(setup, SETUP_FLUSHED, __FUNCTION__))
999 return FALSE;
1000
1001 if (!set_scene_state(setup, SETUP_ACTIVE, __FUNCTION__))
1002 return FALSE;
1003
1004 if (!setup->scene)
1005 return FALSE;
1006
1007 return try_update_scene_state(setup);
1008 }
1009
1010 return TRUE;
1011 }
1012
1013
1014
1015 /* Only caller is lp_setup_vbuf_destroy()
1016 */
1017 void
1018 lp_setup_destroy( struct lp_setup_context *setup )
1019 {
1020 uint i;
1021
1022 lp_setup_reset( setup );
1023
1024 util_unreference_framebuffer_state(&setup->fb);
1025
1026 for (i = 0; i < Elements(setup->fs.current_tex); i++) {
1027 pipe_resource_reference(&setup->fs.current_tex[i], NULL);
1028 }
1029
1030 pipe_resource_reference(&setup->constants.current, NULL);
1031
1032 /* free the scenes in the 'empty' queue */
1033 for (i = 0; i < Elements(setup->scenes); i++) {
1034 struct lp_scene *scene = setup->scenes[i];
1035
1036 if (scene->fence)
1037 lp_fence_wait(scene->fence);
1038
1039 lp_scene_destroy(scene);
1040 }
1041
1042 lp_fence_reference(&setup->last_fence, NULL);
1043
1044 FREE( setup );
1045 }
1046
1047
1048 /**
1049 * Create a new primitive tiling engine. Plug it into the backend of
1050 * the draw module. Currently also creates a rasterizer to use with
1051 * it.
1052 */
1053 struct lp_setup_context *
1054 lp_setup_create( struct pipe_context *pipe,
1055 struct draw_context *draw )
1056 {
1057 struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
1058 struct lp_setup_context *setup;
1059 unsigned i;
1060
1061 setup = CALLOC_STRUCT(lp_setup_context);
1062 if (!setup) {
1063 goto no_setup;
1064 }
1065
1066 lp_setup_init_vbuf(setup);
1067
1068 /* Used only in update_state():
1069 */
1070 setup->pipe = pipe;
1071
1072
1073 setup->num_threads = screen->num_threads;
1074 setup->vbuf = draw_vbuf_stage(draw, &setup->base);
1075 if (!setup->vbuf) {
1076 goto no_vbuf;
1077 }
1078
1079 draw_set_rasterize_stage(draw, setup->vbuf);
1080 draw_set_render(draw, &setup->base);
1081
1082 /* create some empty scenes */
1083 for (i = 0; i < MAX_SCENES; i++) {
1084 setup->scenes[i] = lp_scene_create( pipe );
1085 if (!setup->scenes[i]) {
1086 goto no_scenes;
1087 }
1088 }
1089
1090 setup->triangle = first_triangle;
1091 setup->line = first_line;
1092 setup->point = first_point;
1093
1094 setup->dirty = ~0;
1095
1096 return setup;
1097
1098 no_scenes:
1099 for (i = 0; i < MAX_SCENES; i++) {
1100 if (setup->scenes[i]) {
1101 lp_scene_destroy(setup->scenes[i]);
1102 }
1103 }
1104
1105 setup->vbuf->destroy(setup->vbuf);
1106 no_vbuf:
1107 FREE(setup);
1108 no_setup:
1109 return NULL;
1110 }
1111
1112
1113 /**
1114 * Put a BeginQuery command into all bins.
1115 */
1116 void
1117 lp_setup_begin_query(struct lp_setup_context *setup,
1118 struct llvmpipe_query *pq)
1119 {
1120 /* init the query to its beginning state */
1121 assert(setup->active_query[pq->type] == NULL);
1122
1123 set_scene_state(setup, SETUP_ACTIVE, "begin_query");
1124
1125 setup->active_query[pq->type] = pq;
1126
1127 /* XXX: It is possible that a query is created before the scene
1128 * has been created. This means that setup->scene == NULL resulting
1129 * in the query not being binned and thus is ignored.
1130 */
1131
1132 if (setup->scene) {
1133 if (!lp_scene_bin_everywhere(setup->scene,
1134 LP_RAST_OP_BEGIN_QUERY,
1135 lp_rast_arg_query(pq))) {
1136
1137 if (!lp_setup_flush_and_restart(setup))
1138 return;
1139
1140 if (!lp_scene_bin_everywhere(setup->scene,
1141 LP_RAST_OP_BEGIN_QUERY,
1142 lp_rast_arg_query(pq))) {
1143 return;
1144 }
1145 }
1146 }
1147 }
1148
1149
1150 /**
1151 * Put an EndQuery command into all bins.
1152 */
1153 void
1154 lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
1155 {
1156 set_scene_state(setup, SETUP_ACTIVE, "end_query");
1157
1158 if (pq->type != PIPE_QUERY_TIMESTAMP) {
1159 assert(setup->active_query[pq->type] == pq);
1160 setup->active_query[pq->type] = NULL;
1161 }
1162
1163 /* Setup will automatically re-issue any query which carried over a
1164 * scene boundary, and the rasterizer automatically "ends" queries
1165 * which are active at the end of a scene, so there is no need to
1166 * retry this commands on failure.
1167 */
1168 if (setup->scene) {
1169 /* pq->fence should be the fence of the *last* scene which
1170 * contributed to the query result.
1171 */
1172 lp_fence_reference(&pq->fence, setup->scene->fence);
1173
1174 if (!lp_scene_bin_everywhere(setup->scene,
1175 LP_RAST_OP_END_QUERY,
1176 lp_rast_arg_query(pq))) {
1177 lp_setup_flush(setup, NULL, __FUNCTION__);
1178 }
1179 }
1180 else {
1181 lp_fence_reference(&pq->fence, setup->last_fence);
1182 }
1183 }
1184
1185
1186 boolean
1187 lp_setup_flush_and_restart(struct lp_setup_context *setup)
1188 {
1189 if (0) debug_printf("%s\n", __FUNCTION__);
1190
1191 assert(setup->state == SETUP_ACTIVE);
1192
1193 if (!set_scene_state(setup, SETUP_FLUSHED, __FUNCTION__))
1194 return FALSE;
1195
1196 if (!lp_setup_update_state(setup, TRUE))
1197 return FALSE;
1198
1199 return TRUE;
1200 }
1201
1202