00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00039 #include "sp_context.h"
00040 #include "sp_state.h"
00041 #include "sp_prim_vbuf.h"
00042 #include "sp_prim_setup.h"
00043 #include "sp_setup.h"
00044 #include "draw/draw_context.h"
00045 #include "draw/draw_vbuf.h"
00046 #include "util/u_memory.h"
00047
00048
00049 #define SP_MAX_VBUF_INDEXES 1024
00050 #define SP_MAX_VBUF_SIZE 4096
00051
00052 typedef const float (*cptrf4)[4];
00053
00057 struct softpipe_vbuf_render
00058 {
00059 struct vbuf_render base;
00060 struct softpipe_context *softpipe;
00061 uint prim;
00062 uint vertex_size;
00063 void *vertex_buffer;
00064 };
00065
00066
00068 static struct softpipe_vbuf_render *
00069 softpipe_vbuf_render(struct vbuf_render *vbr)
00070 {
00071 return (struct softpipe_vbuf_render *) vbr;
00072 }
00073
00074
00075 static const struct vertex_info *
00076 sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
00077 {
00078 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00079 return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
00080 }
00081
00082
00083 static void *
00084 sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
00085 ushort vertex_size, ushort nr_vertices)
00086 {
00087 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00088 assert(!cvbr->vertex_buffer);
00089 cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16);
00090 cvbr->vertex_size = vertex_size;
00091 return cvbr->vertex_buffer;
00092 }
00093
00094
00095 static void
00096 sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
00097 unsigned vertex_size, unsigned vertices_used)
00098 {
00099 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00100 align_free(vertices);
00101 assert(vertices == cvbr->vertex_buffer);
00102 cvbr->vertex_buffer = NULL;
00103 }
00104
00105
00106 static boolean
00107 sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
00108 {
00109 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00110
00111
00112
00113
00114 struct setup_context *setup_ctx = sp_draw_setup_context(cvbr->softpipe->setup);
00115
00116 setup_prepare( setup_ctx );
00117
00118
00119
00120 cvbr->prim = prim;
00121 return TRUE;
00122
00123 }
00124
00125
00126 static INLINE cptrf4 get_vert( const void *vertex_buffer,
00127 int index,
00128 int stride )
00129 {
00130 return (cptrf4)((char *)vertex_buffer + index * stride);
00131 }
00132
00133
00134 static void
00135 sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
00136 {
00137 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00138 struct softpipe_context *softpipe = cvbr->softpipe;
00139 unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
00140 unsigned i;
00141 const void *vertex_buffer = cvbr->vertex_buffer;
00142
00143
00144
00145
00146 struct draw_stage *setup = softpipe->setup;
00147 struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup);
00148
00149
00150 switch (cvbr->prim) {
00151 case PIPE_PRIM_POINTS:
00152 for (i = 0; i < nr; i++) {
00153 setup_point( setup_ctx,
00154 get_vert(vertex_buffer, indices[i-0], stride) );
00155 }
00156 break;
00157
00158 case PIPE_PRIM_LINES:
00159 for (i = 1; i < nr; i += 2) {
00160 setup_line( setup_ctx,
00161 get_vert(vertex_buffer, indices[i-1], stride),
00162 get_vert(vertex_buffer, indices[i-0], stride) );
00163 }
00164 break;
00165
00166 case PIPE_PRIM_LINE_STRIP:
00167 for (i = 1; i < nr; i ++) {
00168 setup_line( setup_ctx,
00169 get_vert(vertex_buffer, indices[i-1], stride),
00170 get_vert(vertex_buffer, indices[i-0], stride) );
00171 }
00172 break;
00173
00174 case PIPE_PRIM_LINE_LOOP:
00175 for (i = 1; i < nr; i ++) {
00176 setup_line( setup_ctx,
00177 get_vert(vertex_buffer, indices[i-1], stride),
00178 get_vert(vertex_buffer, indices[i-0], stride) );
00179 }
00180 if (nr) {
00181 setup_line( setup_ctx,
00182 get_vert(vertex_buffer, indices[nr-1], stride),
00183 get_vert(vertex_buffer, indices[0], stride) );
00184 }
00185 break;
00186
00187
00188 case PIPE_PRIM_TRIANGLES:
00189 for (i = 2; i < nr; i += 3) {
00190 setup_tri( setup_ctx,
00191 get_vert(vertex_buffer, indices[i-2], stride),
00192 get_vert(vertex_buffer, indices[i-1], stride),
00193 get_vert(vertex_buffer, indices[i-0], stride));
00194 }
00195 break;
00196
00197 case PIPE_PRIM_TRIANGLE_STRIP:
00198 for (i = 2; i < nr; i += 1) {
00199 setup_tri( setup_ctx,
00200 get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
00201 get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
00202 get_vert(vertex_buffer, indices[i-0], stride));
00203 }
00204 break;
00205
00206 case PIPE_PRIM_TRIANGLE_FAN:
00207 case PIPE_PRIM_POLYGON:
00208 for (i = 2; i < nr; i += 1) {
00209 setup_tri( setup_ctx,
00210 get_vert(vertex_buffer, indices[0], stride),
00211 get_vert(vertex_buffer, indices[i-1], stride),
00212 get_vert(vertex_buffer, indices[i-0], stride));
00213 }
00214 break;
00215 case PIPE_PRIM_QUADS:
00216 for (i = 3; i < nr; i += 4) {
00217 setup_tri( setup_ctx,
00218 get_vert(vertex_buffer, indices[i-3], stride),
00219 get_vert(vertex_buffer, indices[i-2], stride),
00220 get_vert(vertex_buffer, indices[i-0], stride));
00221
00222 setup_tri( setup_ctx,
00223 get_vert(vertex_buffer, indices[i-2], stride),
00224 get_vert(vertex_buffer, indices[i-1], stride),
00225 get_vert(vertex_buffer, indices[i-0], stride));
00226 }
00227 break;
00228 case PIPE_PRIM_QUAD_STRIP:
00229 for (i = 3; i < nr; i += 2) {
00230 setup_tri( setup_ctx,
00231 get_vert(vertex_buffer, indices[i-3], stride),
00232 get_vert(vertex_buffer, indices[i-2], stride),
00233 get_vert(vertex_buffer, indices[i-0], stride));
00234
00235 setup_tri( setup_ctx,
00236 get_vert(vertex_buffer, indices[i-1], stride),
00237 get_vert(vertex_buffer, indices[i-3], stride),
00238 get_vert(vertex_buffer, indices[i-0], stride));
00239 }
00240 break;
00241 default:
00242 assert(0);
00243 }
00244
00245
00246
00247
00248 sp_draw_flush( setup );
00249 }
00250
00251
00256 static void
00257 sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
00258 {
00259 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00260 struct softpipe_context *softpipe = cvbr->softpipe;
00261 struct draw_stage *setup = softpipe->setup;
00262 const void *vertex_buffer = NULL;
00263 const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
00264 unsigned i;
00265 struct setup_context *setup_ctx = sp_draw_setup_context(setup);
00266
00267 vertex_buffer = (void *)get_vert(cvbr->vertex_buffer, start, stride);
00268
00269 switch (cvbr->prim) {
00270 case PIPE_PRIM_POINTS:
00271 for (i = 0; i < nr; i++) {
00272 setup_point( setup_ctx,
00273 get_vert(vertex_buffer, i-0, stride) );
00274 }
00275 break;
00276
00277 case PIPE_PRIM_LINES:
00278 for (i = 1; i < nr; i += 2) {
00279 setup_line( setup_ctx,
00280 get_vert(vertex_buffer, i-1, stride),
00281 get_vert(vertex_buffer, i-0, stride) );
00282 }
00283 break;
00284
00285 case PIPE_PRIM_LINE_STRIP:
00286 for (i = 1; i < nr; i ++) {
00287 setup_line( setup_ctx,
00288 get_vert(vertex_buffer, i-1, stride),
00289 get_vert(vertex_buffer, i-0, stride) );
00290 }
00291 break;
00292
00293 case PIPE_PRIM_LINE_LOOP:
00294 for (i = 1; i < nr; i ++) {
00295 setup_line( setup_ctx,
00296 get_vert(vertex_buffer, i-1, stride),
00297 get_vert(vertex_buffer, i-0, stride) );
00298 }
00299 if (nr) {
00300 setup_line( setup_ctx,
00301 get_vert(vertex_buffer, nr-1, stride),
00302 get_vert(vertex_buffer, 0, stride) );
00303 }
00304 break;
00305
00306
00307 case PIPE_PRIM_TRIANGLES:
00308 for (i = 2; i < nr; i += 3) {
00309 setup_tri( setup_ctx,
00310 get_vert(vertex_buffer, i-2, stride),
00311 get_vert(vertex_buffer, i-1, stride),
00312 get_vert(vertex_buffer, i-0, stride));
00313 }
00314 break;
00315
00316 case PIPE_PRIM_TRIANGLE_STRIP:
00317 for (i = 2; i < nr; i += 1) {
00318 setup_tri( setup_ctx,
00319 get_vert(vertex_buffer, i+(i&1)-2, stride),
00320 get_vert(vertex_buffer, i-(i&1)-1, stride),
00321 get_vert(vertex_buffer, i-0, stride));
00322 }
00323 break;
00324
00325 case PIPE_PRIM_TRIANGLE_FAN:
00326 case PIPE_PRIM_POLYGON:
00327 for (i = 2; i < nr; i += 1) {
00328 setup_tri( setup_ctx,
00329 get_vert(vertex_buffer, 0, stride),
00330 get_vert(vertex_buffer, i-1, stride),
00331 get_vert(vertex_buffer, i-0, stride));
00332 }
00333 break;
00334 case PIPE_PRIM_QUADS:
00335 for (i = 3; i < nr; i += 4) {
00336 setup_tri( setup_ctx,
00337 get_vert(vertex_buffer, i-3, stride),
00338 get_vert(vertex_buffer, i-2, stride),
00339 get_vert(vertex_buffer, i-0, stride));
00340
00341 setup_tri( setup_ctx,
00342 get_vert(vertex_buffer, i-2, stride),
00343 get_vert(vertex_buffer, i-1, stride),
00344 get_vert(vertex_buffer, i-0, stride));
00345 }
00346 break;
00347 case PIPE_PRIM_QUAD_STRIP:
00348 for (i = 3; i < nr; i += 2) {
00349 setup_tri( setup_ctx,
00350 get_vert(vertex_buffer, i-3, stride),
00351 get_vert(vertex_buffer, i-2, stride),
00352 get_vert(vertex_buffer, i-0, stride));
00353
00354 setup_tri( setup_ctx,
00355 get_vert(vertex_buffer, i-1, stride),
00356 get_vert(vertex_buffer, i-3, stride),
00357 get_vert(vertex_buffer, i-0, stride));
00358 }
00359 break;
00360 default:
00361 assert(0);
00362 }
00363 }
00364
00365
00366
00367 static void
00368 sp_vbuf_destroy(struct vbuf_render *vbr)
00369 {
00370 struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
00371 cvbr->softpipe->vbuf_render = NULL;
00372 FREE(cvbr);
00373 }
00374
00375
00380 void
00381 sp_init_vbuf(struct softpipe_context *sp)
00382 {
00383 assert(sp->draw);
00384
00385 sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render);
00386
00387 sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES;
00388 sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
00389
00390 sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;
00391 sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
00392 sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
00393 sp->vbuf_render->base.draw = sp_vbuf_draw;
00394 sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays;
00395 sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices;
00396 sp->vbuf_render->base.destroy = sp_vbuf_destroy;
00397
00398 sp->vbuf_render->softpipe = sp;
00399
00400 sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base);
00401
00402 draw_set_rasterize_stage(sp->draw, sp->vbuf);
00403
00404 draw_set_render(sp->draw, &sp->vbuf_render->base);
00405 }