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 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "pipe/p_util.h"
34 #include "draw/draw_context.h"
35 #include "draw/draw_private.h"
36 #include "draw/draw_pt.h"
39 /* XXX: Shouldn't those two functions below use the '>' operator???
42 static boolean
too_many_verts( struct draw_context
*draw
,
48 static boolean
too_many_elts( struct draw_context
*draw
,
51 return elts
< (16 * 1024);
56 draw_pt_arrays(struct draw_context
*draw
,
61 const boolean pipeline
= draw_need_pipeline(draw
, prim
);
62 const boolean cliptest
= !draw
->rasterizer
->bypass_clipping
;
63 const boolean shading
= !draw
->rasterizer
->bypass_vs
;
64 struct draw_pt_front_end
*frontend
= NULL
;
65 struct draw_pt_middle_end
*middle
= NULL
;
69 * - frontend -- prepare fetch_elts, draw_elts - eg vcache
70 * - middle -- fetch, shade, cliptest, viewport
71 * - pipeline -- the prim pipeline: clipping, wide lines, etc
72 * - backend -- the vbuf_render provided by the driver.
77 if (!cliptest
&& !pipeline
&& !shading
) {
78 /* This is the 'passthrough' path:
80 /* Fetch user verts, emit hw verts:
82 middle
= draw
->pt
.middle
.fetch_emit
;
84 else if (!cliptest
&& !pipeline
) {
85 /* Fetch user verts, run vertex shader, emit hw verts:
87 middle
= draw
->pt
.middle
.fetch_shade_emit
;
90 /* Even though !pipeline, we have to run it to get clipping. We
91 * do know that the pipeline is just the clipping operation, but
92 * that probably doesn't help much.
94 * This is going to be the most important path for a lot of
99 * cliptest and viewport trasform
100 * if no clipped vertices,
105 middle
= draw
->pt
.middle
.fetch_shade_cliptest_pipeline_or_emit
;
107 else if (!cliptest
) {
108 /* Fetch user verts, run vertex shader, run pipeline:
110 middle
= draw
->pt
.middle
.fetch_shade_pipeline
;
113 /* This is what we're currently always doing:
115 /* Fetch user verts, run vertex shader, cliptest, run pipeline:
117 middle
= draw
->pt
.middle
.fetch_shade_cliptest_pipeline
;
120 if (cliptest
|| pipeline
|| shading
)
123 middle
= draw
->pt
.middle
.fetch_emit
;
127 /* If !pipeline, need to make sure we respect the driver's limited
128 * capabilites to receive blocks of vertex data and elements.
132 unsigned vertex_mode
= passthrough
;
133 unsigned nr_verts
= count_vertices( draw
, start
, count
);
134 unsigned hw_prim
= prim
;
137 frontend
= draw
->pt
.front
.vcache
;
138 hw_prim
= reduced_prim(prim
);
141 if (too_many_verts(nr_verts
)) {
142 /* if (is_verts(draw) && can_split(prim)) {
143 draw = draw_arrays_split;
146 frontend
= draw
->pt
.front
.vcache
;
147 hw_prim
= reduced_prim(prim
);
151 if (too_many_elts(count
)) {
153 /* if (is_elts(draw) && can_split(prim)) {
154 draw = draw_elts_split;
157 frontend
= draw
->pt
.front
.vcache
;
158 hw_prim
= reduced_prim(prim
);
162 if (!good_prim(hw_prim
)) {
163 draw
= draw
->pt
.front
.vcache
;
167 frontend
= draw
->pt
.front
.vcache
;
170 /* XXX: need to flush to get prim_vbuf.c to release its allocation??
172 draw_do_flush( draw
, DRAW_FLUSH_BACKEND
);
174 frontend
->prepare( frontend
, middle
);
176 frontend
->run( frontend
,
178 draw_pt_elt_func( draw
),
179 draw_pt_elt_ptr( draw
, start
),
182 frontend
->finish( frontend
);
188 boolean
draw_pt_init( struct draw_context
*draw
)
190 draw
->pt
.middle
.fetch_emit
= draw_pt_fetch_emit( draw
);
191 if (!draw
->pt
.middle
.fetch_emit
)
194 draw
->pt
.front
.vcache
= draw_pt_vcache();
195 if (!draw
->pt
.front
.vcache
)
202 void draw_pt_destroy( struct draw_context
*draw
)
204 if (draw
->pt
.middle
.fetch_emit
) {
205 draw
->pt
.middle
.fetch_emit
->destroy( draw
->pt
.middle
.fetch_emit
);
206 draw
->pt
.middle
.fetch_emit
= NULL
;
209 if (draw
->pt
.front
.vcache
) {
210 draw
->pt
.front
.vcache
->destroy( draw
->pt
.front
.vcache
);
211 draw
->pt
.front
.vcache
= NULL
;