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.
76 if (!cliptest
&& !pipeline
&& !shading
) {
77 /* This is the 'passthrough' path:
79 /* Fetch user verts, emit hw verts:
81 middle
= draw
->pt
.middle
.fetch_emit
;
83 else if (!cliptest
&& !shading
) {
84 /* This is the 'passthrough' path targetting the pipeline backend.
86 /* Fetch user verts, emit pipeline verts, run pipeline:
88 middle
= draw
->pt
.middle
.fetch_pipeline
;
91 else if (!cliptest
&& !pipeline
) {
92 /* Fetch user verts, run vertex shader, emit hw verts:
94 middle
= draw
->pt
.middle
.fetch_shade_emit
;
97 /* Even though !pipeline, we have to run it to get clipping. We
98 * do know that the pipeline is just the clipping operation, but
99 * that probably doesn't help much.
101 * This is going to be the most important path for a lot of
106 * cliptest and viewport trasform
107 * if no clipped vertices,
112 middle
= draw
->pt
.middle
.fetch_shade_cliptest_pipeline_or_emit
;
114 else if (!cliptest
) {
115 /* Fetch user verts, run vertex shader, run pipeline:
117 middle
= draw
->pt
.middle
.fetch_shade_pipeline
;
120 /* This is what we're currently always doing:
122 /* Fetch user verts, run vertex shader, cliptest, run pipeline:
124 middle
= draw
->pt
.middle
.fetch_shade_cliptest_pipeline
;
133 /* If !pipeline, need to make sure we respect the driver's limited
134 * capabilites to receive blocks of vertex data and elements.
138 unsigned vertex_mode
= passthrough
;
139 unsigned nr_verts
= count_vertices( draw
, start
, count
);
140 unsigned hw_prim
= prim
;
143 frontend
= draw
->pt
.front
.vcache
;
144 hw_prim
= reduced_prim(prim
);
147 if (too_many_verts(nr_verts
)) {
148 /* if (is_verts(draw) && can_split(prim)) {
149 draw = draw_arrays_split;
152 frontend
= draw
->pt
.front
.vcache
;
153 hw_prim
= reduced_prim(prim
);
157 if (too_many_elts(count
)) {
159 /* if (is_elts(draw) && can_split(prim)) {
160 draw = draw_elts_split;
163 frontend
= draw
->pt
.front
.vcache
;
164 hw_prim
= reduced_prim(prim
);
168 if (!good_prim(hw_prim
)) {
169 draw
= draw
->pt
.front
.vcache
;
173 frontend
= draw
->pt
.front
.vcache
;
176 /* XXX: need to flush to get prim_vbuf.c to release its allocation??
178 draw_do_flush( draw
, DRAW_FLUSH_BACKEND
);
180 frontend
->prepare( frontend
, prim
, middle
);
182 frontend
->run( frontend
,
183 draw_pt_elt_func( draw
),
184 draw_pt_elt_ptr( draw
, start
),
187 frontend
->finish( frontend
);
193 boolean
draw_pt_init( struct draw_context
*draw
)
195 draw
->pt
.middle
.fetch_emit
= draw_pt_fetch_emit( draw
);
196 if (!draw
->pt
.middle
.fetch_emit
)
199 draw
->pt
.middle
.fetch_pipeline
= draw_pt_fetch_pipeline( draw
);
200 if (!draw
->pt
.middle
.fetch_pipeline
)
203 draw
->pt
.front
.vcache
= draw_pt_vcache( draw
);
204 if (!draw
->pt
.front
.vcache
)
211 void draw_pt_destroy( struct draw_context
*draw
)
213 if (draw
->pt
.middle
.fetch_emit
) {
214 draw
->pt
.middle
.fetch_emit
->destroy( draw
->pt
.middle
.fetch_emit
);
215 draw
->pt
.middle
.fetch_emit
= NULL
;
218 if (draw
->pt
.middle
.fetch_pipeline
) {
219 draw
->pt
.middle
.fetch_pipeline
->destroy( draw
->pt
.middle
.fetch_pipeline
);
220 draw
->pt
.middle
.fetch_pipeline
= NULL
;
223 if (draw
->pt
.front
.vcache
) {
224 draw
->pt
.front
.vcache
->destroy( draw
->pt
.front
.vcache
);
225 draw
->pt
.front
.vcache
= NULL
;