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 **************************************************************************/
29 * Post-transform vertex buffering. This is an optional part of the
30 * softpipe rendering pipeline.
31 * Probably not desired in general, but useful for testing/debuggin.
32 * Enabled/Disabled with SP_VBUF env var.
39 #include "sp_context.h"
41 #include "sp_prim_vbuf.h"
42 #include "draw/draw_context.h"
43 #include "draw/draw_private.h"
44 #include "draw/draw_vbuf.h"
47 #define SP_MAX_VBUF_INDEXES 1024
48 #define SP_MAX_VBUF_SIZE 4096
52 * Subclass of vbuf_render.
54 struct softpipe_vbuf_render
56 struct vbuf_render base
;
57 struct softpipe_context
*softpipe
;
65 static struct softpipe_vbuf_render
*
66 softpipe_vbuf_render(struct vbuf_render
*vbr
)
68 return (struct softpipe_vbuf_render
*) vbr
;
73 static const struct vertex_info
*
74 sp_vbuf_get_vertex_info(struct vbuf_render
*vbr
)
76 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
77 return softpipe_get_vbuf_vertex_info(cvbr
->softpipe
);
82 sp_vbuf_allocate_vertices(struct vbuf_render
*vbr
,
83 ushort vertex_size
, ushort nr_vertices
)
85 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
86 assert(!cvbr
->vertex_buffer
);
87 cvbr
->vertex_buffer
= align_malloc(vertex_size
* nr_vertices
, 16);
88 cvbr
->vertex_size
= vertex_size
;
89 return cvbr
->vertex_buffer
;
94 sp_vbuf_release_vertices(struct vbuf_render
*vbr
, void *vertices
,
95 unsigned vertex_size
, unsigned vertices_used
)
97 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
99 assert(vertices
== cvbr
->vertex_buffer
);
100 cvbr
->vertex_buffer
= NULL
;
105 sp_vbuf_set_primitive(struct vbuf_render
*vbr
, unsigned prim
)
107 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
108 if (prim
== PIPE_PRIM_TRIANGLES
||
109 prim
== PIPE_PRIM_LINES
||
110 prim
== PIPE_PRIM_POINTS
) {
122 * Recalculate prim's determinant.
123 * XXX is this needed?
126 calc_det(struct prim_header
*header
)
129 const float *v0
= header
->v
[0]->data
[0];
130 const float *v1
= header
->v
[1]->data
[0];
131 const float *v2
= header
->v
[2]->data
[0];
133 /* edge vectors e = v0 - v2, f = v1 - v2 */
134 const float ex
= v0
[0] - v2
[0];
135 const float ey
= v0
[1] - v2
[1];
136 const float fx
= v1
[0] - v2
[0];
137 const float fy
= v1
[1] - v2
[1];
139 /* det = cross(e,f).z */
140 header
->det
= ex
* fy
- ey
* fx
;
145 sp_vbuf_draw(struct vbuf_render
*vbr
, const ushort
*indices
, uint nr_indices
)
147 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
148 struct softpipe_context
*softpipe
= cvbr
->softpipe
;
149 struct draw_stage
*setup
= softpipe
->setup
;
150 struct prim_header prim
;
151 unsigned vertex_size
= softpipe
->vertex_info_vbuf
.size
* sizeof(float);
153 void *vertex_buffer
= cvbr
->vertex_buffer
;
156 prim
.reset_line_stipple
= 0;
160 switch (cvbr
->prim
) {
161 case PIPE_PRIM_TRIANGLES
:
162 for (i
= 0; i
< nr_indices
; i
+= 3) {
163 for (j
= 0; j
< 3; j
++)
164 prim
.v
[j
] = (struct vertex_header
*)((char *)vertex_buffer
+
165 indices
[i
+j
] * vertex_size
);
168 setup
->tri( setup
, &prim
);
172 case PIPE_PRIM_LINES
:
173 for (i
= 0; i
< nr_indices
; i
+= 2) {
174 for (j
= 0; j
< 2; j
++)
175 prim
.v
[j
] = (struct vertex_header
*)((char *)vertex_buffer
+
176 indices
[i
+j
] * vertex_size
);
178 setup
->line( setup
, &prim
);
182 case PIPE_PRIM_POINTS
:
183 for (i
= 0; i
< nr_indices
; i
++) {
184 prim
.v
[0] = (struct vertex_header
*)((char *)vertex_buffer
+
185 indices
[i
] * vertex_size
);
186 setup
->point( setup
, &prim
);
191 setup
->flush( setup
, 0 );
196 * This function is hit when the draw module is working in pass-through mode.
197 * It's up to us to convert the vertex array into point/line/tri prims.
200 sp_vbuf_draw_arrays(struct vbuf_render
*vbr
, uint start
, uint nr
)
202 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
203 struct softpipe_context
*softpipe
= cvbr
->softpipe
;
204 struct draw_stage
*setup
= softpipe
->setup
;
205 struct prim_header prim
;
206 const void *vertex_buffer
= cvbr
->vertex_buffer
;
207 const unsigned vertex_size
= softpipe
->vertex_info_vbuf
.size
* sizeof(float);
211 prim
.reset_line_stipple
= 0;
216 (struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size)
218 switch (cvbr
->prim
) {
219 case PIPE_PRIM_POINTS
:
220 for (i
= 0; i
< nr
; i
++) {
221 prim
.v
[0] = VERTEX(i
);
222 setup
->point( setup
, &prim
);
225 case PIPE_PRIM_LINES
:
227 for (i
= 0; i
< nr
; i
+= 2) {
228 prim
.v
[0] = VERTEX(i
);
229 prim
.v
[1] = VERTEX(i
+ 1);
230 setup
->line( setup
, &prim
);
233 case PIPE_PRIM_LINE_STRIP
:
234 for (i
= 1; i
< nr
; i
++) {
235 prim
.v
[0] = VERTEX(i
- 1);
236 prim
.v
[1] = VERTEX(i
);
237 setup
->line( setup
, &prim
);
240 case PIPE_PRIM_TRIANGLES
:
242 for (i
= 0; i
< nr
; i
+= 3) {
243 prim
.v
[0] = VERTEX(i
+ 0);
244 prim
.v
[1] = VERTEX(i
+ 1);
245 prim
.v
[2] = VERTEX(i
+ 2);
247 setup
->tri( setup
, &prim
);
250 case PIPE_PRIM_TRIANGLE_STRIP
:
252 for (i
= 2; i
< nr
; i
++) {
253 prim
.v
[0] = VERTEX(i
- 2);
254 prim
.v
[1] = VERTEX(i
- 1);
255 prim
.v
[2] = VERTEX(i
);
257 setup
->tri( setup
, &prim
);
260 case PIPE_PRIM_TRIANGLE_FAN
:
262 for (i
= 2; i
< nr
; i
++) {
263 prim
.v
[0] = VERTEX(0);
264 prim
.v
[1] = VERTEX(i
- 1);
265 prim
.v
[2] = VERTEX(i
);
267 setup
->tri( setup
, &prim
);
270 case PIPE_PRIM_QUADS
:
272 for (i
= 0; i
< nr
; i
+= 4) {
273 prim
.v
[0] = VERTEX(i
+ 0);
274 prim
.v
[1] = VERTEX(i
+ 1);
275 prim
.v
[2] = VERTEX(i
+ 2);
277 setup
->tri( setup
, &prim
);
279 prim
.v
[0] = VERTEX(i
+ 0);
280 prim
.v
[1] = VERTEX(i
+ 2);
281 prim
.v
[2] = VERTEX(i
+ 3);
283 setup
->tri( setup
, &prim
);
286 case PIPE_PRIM_QUAD_STRIP
:
288 for (i
= 2; i
< nr
; i
+= 2) {
289 prim
.v
[0] = VERTEX(i
- 2);
290 prim
.v
[1] = VERTEX(i
);
291 prim
.v
[2] = VERTEX(i
+ 1);
293 setup
->tri( setup
, &prim
);
295 prim
.v
[0] = VERTEX(i
- 2);
296 prim
.v
[1] = VERTEX(i
+ 1);
297 prim
.v
[2] = VERTEX(i
- 1);
299 setup
->tri( setup
, &prim
);
302 case PIPE_PRIM_POLYGON
:
303 /* draw as tri fan */
304 for (i
= 2; i
< nr
; i
++) {
305 prim
.v
[0] = VERTEX(0);
306 prim
.v
[1] = VERTEX(i
- 1);
307 prim
.v
[2] = VERTEX(i
);
309 setup
->tri( setup
, &prim
);
313 /* XXX finish remaining prim types */
323 sp_vbuf_destroy(struct vbuf_render
*vbr
)
325 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
326 cvbr
->softpipe
->vbuf_render
= NULL
;
332 * Initialize the post-transform vertex buffer information for the given
336 sp_init_vbuf(struct softpipe_context
*sp
)
340 sp
->vbuf_render
= CALLOC_STRUCT(softpipe_vbuf_render
);
342 sp
->vbuf_render
->base
.max_indices
= SP_MAX_VBUF_INDEXES
;
343 sp
->vbuf_render
->base
.max_vertex_buffer_bytes
= SP_MAX_VBUF_SIZE
;
345 sp
->vbuf_render
->base
.get_vertex_info
= sp_vbuf_get_vertex_info
;
346 sp
->vbuf_render
->base
.allocate_vertices
= sp_vbuf_allocate_vertices
;
347 sp
->vbuf_render
->base
.set_primitive
= sp_vbuf_set_primitive
;
348 sp
->vbuf_render
->base
.draw
= sp_vbuf_draw
;
349 sp
->vbuf_render
->base
.draw_arrays
= sp_vbuf_draw_arrays
;
350 sp
->vbuf_render
->base
.release_vertices
= sp_vbuf_release_vertices
;
351 sp
->vbuf_render
->base
.destroy
= sp_vbuf_destroy
;
353 sp
->vbuf_render
->softpipe
= sp
;
355 sp
->vbuf
= draw_vbuf_stage(sp
->draw
, &sp
->vbuf_render
->base
);
357 draw_set_rasterize_stage(sp
->draw
, sp
->vbuf
);
359 draw_set_render(sp
->draw
, &sp
->vbuf_render
->base
);