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
);
113 * Recalculate prim's determinant.
114 * XXX is this needed?
117 calc_det(struct prim_header
*header
)
120 const float *v0
= header
->v
[0]->data
[0];
121 const float *v1
= header
->v
[1]->data
[0];
122 const float *v2
= header
->v
[2]->data
[0];
124 /* edge vectors e = v0 - v2, f = v1 - v2 */
125 const float ex
= v0
[0] - v2
[0];
126 const float ey
= v0
[1] - v2
[1];
127 const float fx
= v1
[0] - v2
[0];
128 const float fy
= v1
[1] - v2
[1];
130 /* det = cross(e,f).z */
131 header
->det
= ex
* fy
- ey
* fx
;
136 sp_vbuf_draw(struct vbuf_render
*vbr
, const ushort
*indices
, uint nr_indices
)
138 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
139 struct softpipe_context
*softpipe
= cvbr
->softpipe
;
140 struct draw_stage
*setup
= softpipe
->setup
;
141 struct prim_header prim
;
142 unsigned vertex_size
= softpipe
->vertex_info_vbuf
.size
* sizeof(float);
144 void *vertex_buffer
= cvbr
->vertex_buffer
;
147 prim
.reset_line_stipple
= 0;
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 prim
.v
[j
] = (struct vertex_header
*)((char *)vertex_buffer
+
156 indices
[i
+j
] * vertex_size
);
159 setup
->tri( setup
, &prim
);
163 case PIPE_PRIM_LINES
:
164 for (i
= 0; i
< nr_indices
; i
+= 2) {
165 for (j
= 0; j
< 2; j
++)
166 prim
.v
[j
] = (struct vertex_header
*)((char *)vertex_buffer
+
167 indices
[i
+j
] * vertex_size
);
169 setup
->line( setup
, &prim
);
173 case PIPE_PRIM_POINTS
:
174 for (i
= 0; i
< nr_indices
; i
++) {
175 prim
.v
[0] = (struct vertex_header
*)((char *)vertex_buffer
+
176 indices
[i
] * vertex_size
);
177 setup
->point( setup
, &prim
);
182 setup
->flush( setup
, 0 );
187 sp_vbuf_destroy(struct vbuf_render
*vbr
)
189 struct softpipe_vbuf_render
*cvbr
= softpipe_vbuf_render(vbr
);
190 cvbr
->softpipe
->vbuf_render
= NULL
;
196 * Initialize the post-transform vertex buffer information for the given
200 sp_init_vbuf(struct softpipe_context
*sp
)
204 sp
->vbuf_render
= CALLOC_STRUCT(softpipe_vbuf_render
);
206 sp
->vbuf_render
->base
.max_indices
= SP_MAX_VBUF_INDEXES
;
207 sp
->vbuf_render
->base
.max_vertex_buffer_bytes
= SP_MAX_VBUF_SIZE
;
209 sp
->vbuf_render
->base
.get_vertex_info
= sp_vbuf_get_vertex_info
;
210 sp
->vbuf_render
->base
.allocate_vertices
= sp_vbuf_allocate_vertices
;
211 sp
->vbuf_render
->base
.set_primitive
= sp_vbuf_set_primitive
;
212 sp
->vbuf_render
->base
.draw
= sp_vbuf_draw
;
213 sp
->vbuf_render
->base
.release_vertices
= sp_vbuf_release_vertices
;
214 sp
->vbuf_render
->base
.destroy
= sp_vbuf_destroy
;
216 sp
->vbuf_render
->softpipe
= sp
;
218 sp
->vbuf
= draw_vbuf_stage(sp
->draw
, &sp
->vbuf_render
->base
);
220 draw_set_rasterize_stage(sp
->draw
, sp
->vbuf
);