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 "sp_prim_setup.h"
44 #include "draw/draw_context.h"
45 #include "draw/draw_vbuf.h"
48 #define SP_MAX_VBUF_INDEXES 1024
49 #define SP_MAX_VBUF_SIZE 4096
51 typedef const float (*cptrf4
)[4];
54 * Subclass of vbuf_render.
56 struct softpipe_vbuf_render
58 struct vbuf_render base
;
59 struct softpipe_context
*softpipe
;
67 static struct softpipe_vbuf_render
*
68 softpipe_vbuf_render(struct vbuf_render
*vbr
)
70 return (struct softpipe_vbuf_render
*) vbr
;
74 static const struct vertex_info
*
75 sp_vbuf_get_vertex_info(struct vbuf_render
*vbr
)
77 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
78 return softpipe_get_vbuf_vertex_info(cvbr
->softpipe
);
83 sp_vbuf_allocate_vertices(struct vbuf_render
*vbr
,
84 ushort vertex_size
, ushort nr_vertices
)
86 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
87 assert(!cvbr
->vertex_buffer
);
88 cvbr
->vertex_buffer
= align_malloc(vertex_size
* nr_vertices
, 16);
89 cvbr
->vertex_size
= vertex_size
;
90 return cvbr
->vertex_buffer
;
95 sp_vbuf_release_vertices(struct vbuf_render
*vbr
, void *vertices
,
96 unsigned vertex_size
, unsigned vertices_used
)
98 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
100 assert(vertices
== cvbr
->vertex_buffer
);
101 cvbr
->vertex_buffer
= NULL
;
106 sp_vbuf_set_primitive(struct vbuf_render
*vbr
, unsigned prim
)
108 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
110 /* XXX: break this dependency - make setup_context live under
111 * softpipe, rename the old "setup" draw stage to something else.
113 struct setup_context
*setup_ctx
= sp_draw_setup_context(cvbr
->softpipe
->setup
);
115 setup_prepare( setup_ctx
);
119 if (prim
== PIPE_PRIM_TRIANGLES
||
120 prim
== PIPE_PRIM_LINES
||
121 prim
== PIPE_PRIM_POINTS
) {
135 sp_vbuf_draw(struct vbuf_render
*vbr
, const ushort
*indices
, uint nr_indices
)
137 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
138 struct softpipe_context
*softpipe
= cvbr
->softpipe
;
139 unsigned vertex_size
= softpipe
->vertex_info_vbuf
.size
* sizeof(float);
141 void *vertex_buffer
= cvbr
->vertex_buffer
;
144 /* XXX: break this dependency - make setup_context live under
145 * softpipe, rename the old "setup" draw stage to something else.
147 struct draw_stage
*setup
= softpipe
->setup
;
148 struct setup_context
*setup_ctx
= sp_draw_setup_context(softpipe
->setup
);
151 switch (cvbr
->prim
) {
152 case PIPE_PRIM_TRIANGLES
:
153 for (i
= 0; i
< nr_indices
; i
+= 3) {
154 for (j
= 0; j
< 3; j
++)
155 v
[j
] = (cptrf4
)((char *)vertex_buffer
+
156 indices
[i
+j
] * vertex_size
);
158 setup_tri( setup_ctx
,
165 case PIPE_PRIM_LINES
:
166 for (i
= 0; i
< nr_indices
; i
+= 2) {
167 for (j
= 0; j
< 2; j
++)
168 v
[j
] = (cptrf4
)((char *)vertex_buffer
+
169 indices
[i
+j
] * vertex_size
);
171 setup_line( setup_ctx
,
177 case PIPE_PRIM_POINTS
:
178 for (i
= 0; i
< nr_indices
; i
++) {
179 v
[0] = (cptrf4
)((char *)vertex_buffer
+
180 indices
[i
] * vertex_size
);
182 setup_point( setup_ctx
,
188 /* XXX: why are we calling this??? If we had to call something, it
189 * would be a function in sp_setup.c:
191 sp_draw_flush( setup
);
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 const void *vertex_buffer
= cvbr
->vertex_buffer
;
206 const unsigned vertex_size
= softpipe
->vertex_info_vbuf
.size
* sizeof(float);
208 struct setup_context
*setup_ctx
= sp_draw_setup_context(setup
);
212 (cptrf4) ((char *) vertex_buffer + (I) * vertex_size)
214 switch (cvbr
->prim
) {
215 case PIPE_PRIM_POINTS
:
216 for (i
= 0; i
< nr
; i
++) {
218 setup_point( setup_ctx
, v
[0] );
221 case PIPE_PRIM_LINES
:
223 for (i
= 0; i
< nr
; i
+= 2) {
225 v
[1] = VERTEX(i
+ 1);
226 setup_line( setup_ctx
, v
[0], v
[1] );
229 case PIPE_PRIM_LINE_STRIP
:
230 for (i
= 1; i
< nr
; i
++) {
231 v
[0] = VERTEX(i
- 1);
233 setup_line( setup_ctx
, v
[0], v
[1] );
236 case PIPE_PRIM_TRIANGLES
:
238 for (i
= 0; i
< nr
; i
+= 3) {
239 v
[0] = VERTEX(i
+ 0);
240 v
[1] = VERTEX(i
+ 1);
241 v
[2] = VERTEX(i
+ 2);
242 setup_tri( setup_ctx
,
248 case PIPE_PRIM_TRIANGLE_STRIP
:
250 for (i
= 2; i
< nr
; i
++) {
251 v
[0] = VERTEX(i
- 2);
252 v
[1] = VERTEX(i
- 1);
254 setup_tri( setup_ctx
,
260 case PIPE_PRIM_TRIANGLE_FAN
:
262 for (i
= 2; i
< nr
; i
++) {
264 v
[1] = VERTEX(i
- 1);
266 setup_tri( setup_ctx
,
272 case PIPE_PRIM_QUADS
:
274 for (i
= 0; i
< nr
; i
+= 4) {
275 v
[0] = VERTEX(i
+ 0);
276 v
[1] = VERTEX(i
+ 1);
277 v
[2] = VERTEX(i
+ 2);
278 setup_tri( setup_ctx
,
283 v
[0] = VERTEX(i
+ 0);
284 v
[1] = VERTEX(i
+ 2);
285 v
[2] = VERTEX(i
+ 3);
286 setup_tri( setup_ctx
,
292 case PIPE_PRIM_QUAD_STRIP
:
294 for (i
= 2; i
< nr
; i
+= 2) {
295 v
[0] = VERTEX(i
- 2);
297 v
[2] = VERTEX(i
+ 1);
298 setup_tri( setup_ctx
,
303 v
[0] = VERTEX(i
- 2);
304 v
[1] = VERTEX(i
+ 1);
305 v
[2] = VERTEX(i
- 1);
306 setup_tri( setup_ctx
,
312 case PIPE_PRIM_POLYGON
:
313 /* draw as tri fan */
314 for (i
= 2; i
< nr
; i
++) {
316 v
[1] = VERTEX(i
- 1);
318 setup_tri( setup_ctx
,
325 /* XXX finish remaining prim types */
335 sp_vbuf_destroy(struct vbuf_render
*vbr
)
337 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
338 cvbr
->softpipe
->vbuf_render
= NULL
;
344 * Initialize the post-transform vertex buffer information for the given
348 sp_init_vbuf(struct softpipe_context
*sp
)
352 sp
->vbuf_render
= CALLOC_STRUCT(softpipe_vbuf_render
);
354 sp
->vbuf_render
->base
.max_indices
= SP_MAX_VBUF_INDEXES
;
355 sp
->vbuf_render
->base
.max_vertex_buffer_bytes
= SP_MAX_VBUF_SIZE
;
357 sp
->vbuf_render
->base
.get_vertex_info
= sp_vbuf_get_vertex_info
;
358 sp
->vbuf_render
->base
.allocate_vertices
= sp_vbuf_allocate_vertices
;
359 sp
->vbuf_render
->base
.set_primitive
= sp_vbuf_set_primitive
;
360 sp
->vbuf_render
->base
.draw
= sp_vbuf_draw
;
361 sp
->vbuf_render
->base
.draw_arrays
= sp_vbuf_draw_arrays
;
362 sp
->vbuf_render
->base
.release_vertices
= sp_vbuf_release_vertices
;
363 sp
->vbuf_render
->base
.destroy
= sp_vbuf_destroy
;
365 sp
->vbuf_render
->softpipe
= sp
;
367 sp
->vbuf
= draw_vbuf_stage(sp
->draw
, &sp
->vbuf_render
->base
);
369 draw_set_rasterize_stage(sp
->draw
, sp
->vbuf
);
371 draw_set_render(sp
->draw
, &sp
->vbuf_render
->base
);