1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 * Builds per-tile display lists and executes them on calls to
36 #include "util/u_math.h"
37 #include "util/u_memory.h"
39 void lp_setup_new_cmd_block( struct cmd_block_list
*list
)
41 struct cmd_block
*block
= MALLOC_STRUCT(cmd_block
);
42 list
->tail
->next
= block
;
48 void lp_setup_new_data_block( struct data_block_list
*list
)
50 struct data_block
*block
= MALLOC_STRUCT(data_block
);
51 list
->tail
->next
= block
;
57 static void reset_context( struct setup_context
*setup
)
59 for (i
= 0; i
< setup
->tiles_x
; i
++) {
60 for (j
= 0; j
< setup
->tiles_y
; j
++) {
61 struct cmd_block_list
*list
= scene
->tile
[i
][j
];
62 struct cmd_block
*block
;
63 struct cmd_block
*tmp
;
65 for (block
= list
->first
; block
!= list
->tail
; block
= tmp
) {
70 list
->first
= list
->tail
;
75 struct data_block_list
*list
= &scene
->data
;
76 struct data_block
*block
, *tmp
;
78 for (block
= list
->first
; block
!= list
->tail
; block
= tmp
) {
83 list
->first
= list
->tail
;
90 /* Add a command to all active bins.
92 static void bin_everywhere( struct setup_context
*setup
,
94 const union lp_rast_cmd_arg
*arg
)
97 for (i
= 0; i
< setup
->tiles_x
; i
++)
98 for (j
= 0; j
< setup
->tiles_y
; j
++)
99 bin_cmd( setup
, &setup
->tile
[i
][j
], cmd
, arg
);
104 rasterize_bins( struct setup_context
*setup
,
105 struct lp_rast
*rast
,
106 boolean write_depth
)
108 lp_rast_bind_color( rast
,
112 lp_rast_bind_depth( rast
,
114 write_depth
); /* WRITE */
116 for (i
= 0; i
< scene
->tiles_x
; i
++) {
117 for (j
= 0; j
< scene
->tiles_y
; j
++) {
119 lp_rast_start_tile( rast
,
123 for (block
= scene
->tile
[i
][j
].first
; block
; block
= block
->next
) {
124 for (k
= 0; k
< block
->nr_cmds
; k
++) {
125 block
->cmd
[k
].func( rast
, block
->cmd
[k
].arg
);
129 lp_rast_finish_tile( rast
);
133 lp_setup_free_data( setup
);
139 begin_binning( struct setup_context
*setup
)
141 if (setup
->fb
.color
) {
142 if (setup
->fb
.clear_color
)
143 bin_everywhere( setup
,
145 &setup
->clear_data
);
147 bin_everywhere( setup
,
152 if (setup
->fb
.zstencil
) {
153 if (setup
->fb
.clear_zstencil
)
154 bin_everywhere( setup
,
155 lp_rast_clear_zstencil
,
156 &setup
->clear_data
);
158 bin_everywhere( setup
,
159 lp_rast_load_zstencil
,
165 /* This basically bins and then flushes any outstanding full-screen
168 * TODO: fast path for fullscreen clears and no triangles.
171 execute_clears( struct setup_context
*setup
)
173 begin_binning( setup
);
174 rasterize_bins( setup
);
179 set_state( struct setup_context
*setup
,
182 unsigned old_state
= setup
->state
;
184 if (old_state
== new_state
)
189 if (old_state
== SETUP_FLUSHED
)
190 setup_begin_binning( setup
);
194 if (old_state
== SETUP_ACTIVE
) {
201 if (old_state
== SETUP_CLEAR
)
202 execute_clears( setup
);
204 rasterize_bins( setup
);
208 setup
->state
= new_state
;
213 lp_setup_flush( struct setup_context
*setup
,
216 set_state( setup
, SETUP_FLUSHED
);
221 lp_setup_bind_framebuffer( struct setup_context
*setup
,
222 struct pipe_surface
*color
,
223 struct pipe_surface
*zstencil
)
225 unsigned width
, height
;
227 set_state( setup
, SETUP_FLUSHED
);
229 pipe_surface_reference( &setup
->fb
.color
, color
);
230 pipe_surface_reference( &setup
->fb
.zstencil
, zstencil
);
232 width
= MAX2( color
->width
, zstencil
->width
);
233 height
= MAX2( color
->height
, zstencil
->height
);
235 setup
->tiles_x
= align( width
, TILESIZE
) / TILESIZE
;
236 setup
->tiles_y
= align( height
, TILESIZE
) / TILESIZE
;
240 lp_setup_clear( struct setup_context
*setup
,
241 const float *clear_color
,
243 unsigned clear_stencil
,
246 if (setup
->state
== SETUP_ACTIVE
) {
247 struct lp_rast_clear_info
*clear_info
;
250 clear_info
= alloc_clear_info( setup
);
252 if (flags
& PIPE_CLEAR_COLOR
) {
256 bin_everywhere(setup
, lp_rast_clear_color
, clear_info
);
259 if (flags
& PIPE_CLEAR_DEPTH_STENCIL
) {
260 pack_depth_stencil( setup
,
265 bin_everywhere(setup
, lp_rast_clear_zstencil
, clear_info
);
269 set_state( setup
, SETUP_CLEARED
);
270 setup
->clear
.flags
|= flags
;
272 if (flags
& PIPE_CLEAR_COLOR
) {
273 memcpy(setup
->clear
.color
, color
, sizeof setup
->clear
.color
);
276 if (flags
& PIPE_CLEAR_DEPTH_STENCIL
) {
277 setup
->clear
.depth
= clear_depth
;
278 setup
->clear
.stencil
= clear_stencil
;
285 lp_setup_set_fs_inputs( struct setup_context
*setup
,
286 const enum lp_interp
*interp
,
289 memcpy( setup
->interp
, interp
, nr
* sizeof interp
[0] );
294 first_triangle( struct setup_context
*setup
,
295 const float (*v0
)[4],
296 const float (*v1
)[4],
297 const float (*v2
)[4])
299 set_state( setup
, STATE_ACTIVE
);
300 setup_choose_triangle( setup
, v0
, v1
, v2
);
305 /* Stubs for lines & points for now:
308 lp_setup_point(struct setup_context
*setup
,
309 const float (*v0
)[4])
311 setup
->point( setup
, v0
);
315 lp_setup_line(struct setup_context
*setup
,
316 const float (*v0
)[4],
317 const float (*v1
)[4])
319 setup
->line( setup
, v0
, v1
);
323 lp_setup_triangle(struct setup_context
*setup
,
324 const float (*v0
)[4],
325 const float (*v1
)[4],
326 const float (*v2
)[4])
328 setup
->triangle( setup
, v0
, v1
, v2
);
332 void setup_destroy_context( struct setup_context
*setup
)
334 lp_rast_destroy( setup
->rast
);
340 * Create a new primitive tiling engine. Currently also creates a
341 * rasterizer to use with it.
343 struct setup_context
*setup_create_context( void )
345 struct setup_context
*setup
= CALLOC_STRUCT(setup_context
);
347 setup
->rast
= lp_rast_create( void );
351 for (i
= 0; i
< TILES_X
; i
++)
352 for (j
= 0; j
< TILES_Y
; j
++)
353 setup
->tile
[i
][j
].first
=
354 setup
->tile
[i
][j
].next
= CALLOC_STRUCT(cmd_block
);