gallium: reduce signed/unsigned warnings
[mesa.git] / src / gallium / auxiliary / draw / draw_passthrough.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 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33
34 /* This code is a prototype of what a passhthrough vertex shader might
35 * look like.
36 *
37 * Probably the best approach for us is to do:
38 * - vertex fetch
39 * - vertex shader
40 * - cliptest / viewport transform
41 *
42 * in one step, then examine the clipOrMask & choose between two paths:
43 *
44 * Either:
45 * - build primitive headers
46 * - clip and the primitive path
47 * - build clipped vertex buffers,
48 * - vertex-emit to vbuf buffers
49 *
50 * Or, if no clipping:
51 * - vertex-emit directly to vbuf buffers
52 *
53 * But when bypass clipping is enabled, we just take the latter
54 * choice. If (some new) passthrough-vertex-shader flag is also set,
55 * the pipeline degenerates to:
56 *
57 * - vertex fetch
58 * - vertex emit to vbuf buffers
59 *
60 * Which is what is prototyped here.
61 */
62 #include "pipe/p_util.h"
63 #include "draw/draw_context.h"
64 #include "draw/draw_private.h"
65 #include "draw/draw_vbuf.h"
66 #include "draw/draw_vertex.h"
67
68
69
70 /* Example of a fetch/emit passthrough shader which could be
71 * generated when bypass_clipping is enabled on a passthrough vertex
72 * shader.
73 */
74 static void fetch_xyz_rgb_st( struct draw_context *draw,
75 float *out,
76 unsigned start,
77 unsigned count )
78 {
79 const unsigned *pitch = draw->vertex_fetch.pitch;
80 const ubyte **src = draw->vertex_fetch.src_ptr;
81 unsigned i;
82
83 const ubyte *xyzw = src[0] + start * pitch[0];
84 const ubyte *rgba = src[1] + start * pitch[1];
85 const ubyte *st = src[2] + start * pitch[2];
86
87 /* loop over vertex attributes (vertex shader inputs)
88 */
89 for (i = 0; i < count; i++) {
90 {
91 const float *in = (const float *)xyzw; xyzw += pitch[0];
92 /* decode input, encode output. Assume both are float[4] */
93 out[0] = in[0];
94 out[1] = in[1];
95 out[2] = in[2];
96 out[3] = in[3];
97 }
98
99 {
100 const float *in = (const float *)rgba; rgba += pitch[1];
101 /* decode input, encode output. Assume both are float[4] */
102 out[4] = in[0];
103 out[5] = in[1];
104 out[6] = in[2];
105 out[7] = in[3];
106 }
107
108 {
109 const float *in = (const float *)st; st += pitch[2];
110 /* decode input, encode output. Assume both are float[2] */
111 out[8] = in[0];
112 out[9] = in[1];
113 }
114
115 out += 10;
116 }
117 }
118
119
120 static boolean update_shader( struct draw_context *draw )
121 {
122 const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
123
124 unsigned nr_attrs = vinfo->num_attribs;
125 unsigned i;
126
127 for (i = 0; i < nr_attrs; i++) {
128 unsigned buf = draw->vertex_element[i].vertex_buffer_index;
129
130 draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
131 draw->vertex_buffer[buf].buffer_offset +
132 draw->vertex_element[i].src_offset;
133
134 draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
135 draw->vertex_fetch.fetch[i] = NULL;
136 }
137
138 draw->vertex_fetch.nr_attrs = nr_attrs;
139 draw->vertex_fetch.fetch_func = NULL;
140 draw->vertex_fetch.pt_fetch = NULL;
141
142 draw->pt.hw_vertex_size = vinfo->size * 4;
143
144 /* Just trying to figure out how this would work:
145 */
146 if (nr_attrs == 3 &&
147 0 /* some other tests */)
148 {
149 draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st;
150 assert(vinfo->size == 10);
151 return TRUE;
152 }
153
154 return FALSE;
155 }
156
157
158
159 static boolean set_prim( struct draw_context *draw,
160 unsigned prim )
161 {
162 assert(!draw->user.elts);
163
164 draw->pt.prim = prim;
165
166 switch (prim) {
167 case PIPE_PRIM_LINE_LOOP:
168 case PIPE_PRIM_QUADS:
169 case PIPE_PRIM_QUAD_STRIP:
170 return FALSE;
171 default:
172 draw->render->set_primitive( draw->render, prim );
173 return TRUE;
174 }
175 }
176
177
178
179 boolean
180 draw_passthrough_arrays(struct draw_context *draw,
181 unsigned prim,
182 unsigned start,
183 unsigned count)
184 {
185 float *hw_verts;
186
187 if (!set_prim(draw, prim))
188 return FALSE;
189
190 if (!update_shader( draw ))
191 return FALSE;
192
193 hw_verts = draw->render->allocate_vertices( draw->render,
194 draw->pt.hw_vertex_size,
195 count );
196
197 if (!hw_verts)
198 return FALSE;
199
200 /* Single routine to fetch vertices, run shader and emit HW verts.
201 * Clipping and viewport transformation are done on hardware.
202 */
203 draw->vertex_fetch.pt_fetch( draw,
204 hw_verts,
205 start, count );
206
207 /* Draw arrays path to avoid re-emitting index list again and
208 * again.
209 */
210 draw->render->draw_arrays( draw->render,
211 start,
212 count );
213
214
215 draw->render->release_vertices( draw->render,
216 hw_verts,
217 draw->pt.hw_vertex_size,
218 count );
219
220 return TRUE;
221 }
222