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
00028
00029
00030
00031
00032
00033
00034 #include "util/u_math.h"
00035 #include "util/u_memory.h"
00036 #include "draw/draw_context.h"
00037 #include "draw/draw_private.h"
00038 #include "draw/draw_vbuf.h"
00039 #include "draw/draw_vertex.h"
00040 #include "draw/draw_pt.h"
00041 #include "draw/draw_vs.h"
00042
00043 #include "translate/translate.h"
00044
00045 struct fetch_shade_emit;
00046
00047
00048
00049
00050 struct fetch_shade_emit {
00051 struct draw_pt_middle_end base;
00052 struct draw_context *draw;
00053
00054
00055
00056
00057 const float *constants;
00058 unsigned pitch[PIPE_MAX_ATTRIBS];
00059 const ubyte *src[PIPE_MAX_ATTRIBS];
00060 unsigned prim;
00061
00062 struct draw_vs_varient_key key;
00063 struct draw_vs_varient *active;
00064
00065
00066 const struct vertex_info *vinfo;
00067 };
00068
00069
00070
00071
00072 static void fse_prepare( struct draw_pt_middle_end *middle,
00073 unsigned prim,
00074 unsigned opt,
00075 unsigned *max_vertices )
00076 {
00077 struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
00078 struct draw_context *draw = fse->draw;
00079 unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs;
00080 const struct vertex_info *vinfo;
00081 unsigned i;
00082 unsigned nr_vbs = 0;
00083
00084
00085 if (!draw->render->set_primitive( draw->render,
00086 prim )) {
00087 assert(0);
00088 return;
00089 }
00090
00091
00092
00093 fse->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
00094
00095
00096
00097 fse->key.output_stride = vinfo->size * 4;
00098 fse->key.nr_outputs = vinfo->num_attribs;
00099 fse->key.nr_inputs = num_vs_inputs;
00100
00101 fse->key.nr_elements = MAX2(fse->key.nr_outputs,
00102 fse->key.nr_inputs);
00103
00104 fse->key.viewport = !draw->identity_viewport;
00105 fse->key.clip = !draw->bypass_clipping;
00106 fse->key.const_vbuffers = 0;
00107
00108 memset(fse->key.element, 0,
00109 fse->key.nr_elements * sizeof(fse->key.element[0]));
00110
00111 for (i = 0; i < num_vs_inputs; i++) {
00112 const struct pipe_vertex_element *src = &draw->pt.vertex_element[i];
00113 fse->key.element[i].in.format = src->src_format;
00114
00115
00116
00117
00118 fse->key.element[i].in.buffer = src->vertex_buffer_index;
00119 fse->key.element[i].in.offset = src->src_offset;
00120 nr_vbs = MAX2(nr_vbs, src->vertex_buffer_index + 1);
00121 }
00122
00123 for (i = 0; i < 5 && i < nr_vbs; i++) {
00124 if (draw->pt.vertex_buffer[i].pitch == 0)
00125 fse->key.const_vbuffers |= (1<<i);
00126 }
00127
00128 if (0) debug_printf("%s: lookup const_vbuffers: %x\n", __FUNCTION__, fse->key.const_vbuffers);
00129
00130 {
00131 unsigned dst_offset = 0;
00132
00133 for (i = 0; i < vinfo->num_attribs; i++) {
00134 unsigned emit_sz = 0;
00135
00136 switch (vinfo->attrib[i].emit) {
00137 case EMIT_4F:
00138 emit_sz = 4 * sizeof(float);
00139 break;
00140 case EMIT_3F:
00141 emit_sz = 3 * sizeof(float);
00142 break;
00143 case EMIT_2F:
00144 emit_sz = 2 * sizeof(float);
00145 break;
00146 case EMIT_1F:
00147 emit_sz = 1 * sizeof(float);
00148 break;
00149 case EMIT_1F_PSIZE:
00150 emit_sz = 1 * sizeof(float);
00151 break;
00152 case EMIT_4UB:
00153 emit_sz = 4 * sizeof(ubyte);
00154 break;
00155 default:
00156 assert(0);
00157 break;
00158 }
00159
00160
00161
00162
00163
00164 fse->key.element[i].out.format = vinfo->attrib[i].emit;
00165 fse->key.element[i].out.vs_output = vinfo->attrib[i].src_index;
00166 fse->key.element[i].out.offset = dst_offset;
00167
00168 dst_offset += emit_sz;
00169 assert(fse->key.output_stride >= dst_offset);
00170 }
00171 }
00172
00173
00174 fse->active = draw_vs_lookup_varient( draw->vs.vertex_shader,
00175 &fse->key );
00176
00177 if (!fse->active) {
00178 assert(0);
00179 return ;
00180 }
00181
00182 if (0) debug_printf("%s: found const_vbuffers: %x\n", __FUNCTION__,
00183 fse->active->key.const_vbuffers);
00184
00185
00186
00187 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00188 fse->active->set_buffer( fse->active,
00189 i,
00190 ((const ubyte *) draw->pt.user.vbuffer[i] +
00191 draw->pt.vertex_buffer[i].buffer_offset),
00192 draw->pt.vertex_buffer[i].pitch );
00193 }
00194
00195 *max_vertices = (draw->render->max_vertex_buffer_bytes /
00196 (vinfo->size * 4));
00197
00198
00199
00200
00201
00202
00203
00204
00205 *max_vertices = *max_vertices & ~1;
00206
00207
00208
00209
00210 if (1) {
00211 struct draw_vertex_shader *vs = draw->vs.vertex_shader;
00212 vs->prepare(vs, draw);
00213 }
00214
00215
00216
00217 }
00218
00219
00220
00221
00222
00223
00224
00225 static void fse_run_linear( struct draw_pt_middle_end *middle,
00226 unsigned start,
00227 unsigned count )
00228 {
00229 struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
00230 struct draw_context *draw = fse->draw;
00231 char *hw_verts;
00232
00233
00234
00235 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00236
00237 hw_verts = draw->render->allocate_vertices( draw->render,
00238 (ushort)fse->key.output_stride,
00239 (ushort)count );
00240
00241 if (!hw_verts) {
00242 assert(0);
00243 return;
00244 }
00245
00246
00247
00248
00249
00250 fse->active->run_linear( fse->active,
00251 start, count,
00252 hw_verts );
00253
00254
00255
00256
00257 draw->render->draw_arrays( draw->render,
00258 0,
00259 count );
00260
00261 if (0) {
00262 unsigned i;
00263 for (i = 0; i < count; i++) {
00264 debug_printf("\n\n%s vertex %d: (stride %d, offset %d)\n", __FUNCTION__, i,
00265 fse->key.output_stride,
00266 fse->key.output_stride * i);
00267
00268 draw_dump_emitted_vertex( fse->vinfo,
00269 (const uint8_t *)hw_verts + fse->key.output_stride * i );
00270 }
00271 }
00272
00273
00274 draw->render->release_vertices( draw->render,
00275 hw_verts,
00276 fse->key.output_stride,
00277 count );
00278 }
00279
00280
00281 static void
00282 fse_run(struct draw_pt_middle_end *middle,
00283 const unsigned *fetch_elts,
00284 unsigned fetch_count,
00285 const ushort *draw_elts,
00286 unsigned draw_count )
00287 {
00288 struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
00289 struct draw_context *draw = fse->draw;
00290 void *hw_verts;
00291
00292
00293
00294 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00295
00296 hw_verts = draw->render->allocate_vertices( draw->render,
00297 (ushort)fse->key.output_stride,
00298 (ushort)fetch_count );
00299 if (!hw_verts) {
00300 assert(0);
00301 return;
00302 }
00303
00304
00305
00306
00307 fse->active->run_elts( fse->active,
00308 fetch_elts,
00309 fetch_count,
00310 hw_verts );
00311
00312 draw->render->draw( draw->render,
00313 draw_elts,
00314 draw_count );
00315
00316 if (0) {
00317 unsigned i;
00318 for (i = 0; i < fetch_count; i++) {
00319 debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
00320 draw_dump_emitted_vertex( fse->vinfo,
00321 (const uint8_t *)hw_verts +
00322 fse->key.output_stride * i );
00323 }
00324 }
00325
00326
00327 draw->render->release_vertices( draw->render,
00328 hw_verts,
00329 fse->key.output_stride,
00330 fetch_count );
00331
00332 }
00333
00334
00335
00336 static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,
00337 unsigned start,
00338 unsigned count,
00339 const ushort *draw_elts,
00340 unsigned draw_count )
00341 {
00342 struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
00343 struct draw_context *draw = fse->draw;
00344 char *hw_verts;
00345
00346
00347
00348 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00349
00350 hw_verts = draw->render->allocate_vertices( draw->render,
00351 (ushort)fse->key.output_stride,
00352 (ushort)count );
00353
00354 if (!hw_verts) {
00355 return FALSE;
00356 }
00357
00358
00359
00360
00361
00362 fse->active->run_linear( fse->active,
00363 start, count,
00364 hw_verts );
00365
00366
00367 draw->render->draw( draw->render,
00368 draw_elts,
00369 draw_count );
00370
00371
00372
00373 draw->render->release_vertices( draw->render,
00374 hw_verts,
00375 fse->key.output_stride,
00376 count );
00377
00378 return TRUE;
00379 }
00380
00381
00382
00383 static void fse_finish( struct draw_pt_middle_end *middle )
00384 {
00385 }
00386
00387
00388 static void
00389 fse_destroy( struct draw_pt_middle_end *middle )
00390 {
00391 FREE(middle);
00392 }
00393
00394 struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw )
00395 {
00396 struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit);
00397 if (!fse)
00398 return NULL;
00399
00400 fse->base.prepare = fse_prepare;
00401 fse->base.run = fse_run;
00402 fse->base.run_linear = fse_run_linear;
00403 fse->base.run_linear_elts = fse_run_linear_elts;
00404 fse->base.finish = fse_finish;
00405 fse->base.destroy = fse_destroy;
00406 fse->draw = draw;
00407
00408 return &fse->base;
00409 }