Go to the source code of this file.
Data Structures | |
struct | fetch_emit_middle_end |
Functions | |
static void | fetch_emit_prepare (struct draw_pt_middle_end *middle, unsigned prim, unsigned opt, unsigned *max_vertices) |
static void | fetch_emit_run (struct draw_pt_middle_end *middle, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, unsigned draw_count) |
static void | fetch_emit_run_linear (struct draw_pt_middle_end *middle, unsigned start, unsigned count) |
static boolean | fetch_emit_run_linear_elts (struct draw_pt_middle_end *middle, unsigned start, unsigned count, const ushort *draw_elts, unsigned draw_count) |
static void | fetch_emit_finish (struct draw_pt_middle_end *middle) |
static void | fetch_emit_destroy (struct draw_pt_middle_end *middle) |
struct draw_pt_middle_end * | draw_pt_fetch_emit (struct draw_context *draw) |
struct draw_pt_middle_end* draw_pt_fetch_emit | ( | struct draw_context * | draw | ) | [read] |
Definition at line 390 of file draw_pt_fetch_emit.c.
References fetch_emit_middle_end::base, fetch_emit_middle_end::cache, CALLOC_STRUCT, draw_pt_middle_end::destroy, fetch_emit_middle_end::draw, fetch_emit_destroy(), fetch_emit_finish(), fetch_emit_prepare(), fetch_emit_run(), fetch_emit_run_linear(), fetch_emit_run_linear_elts(), draw_pt_middle_end::finish, FREE, draw_pt_middle_end::prepare, draw_pt_middle_end::run, draw_pt_middle_end::run_linear, draw_pt_middle_end::run_linear_elts, and translate_cache_create().
00391 { 00392 struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end ); 00393 if (fetch_emit == NULL) 00394 return NULL; 00395 00396 fetch_emit->cache = translate_cache_create(); 00397 if (!fetch_emit->cache) { 00398 FREE(fetch_emit); 00399 return NULL; 00400 } 00401 00402 fetch_emit->base.prepare = fetch_emit_prepare; 00403 fetch_emit->base.run = fetch_emit_run; 00404 fetch_emit->base.run_linear = fetch_emit_run_linear; 00405 fetch_emit->base.run_linear_elts = fetch_emit_run_linear_elts; 00406 fetch_emit->base.finish = fetch_emit_finish; 00407 fetch_emit->base.destroy = fetch_emit_destroy; 00408 00409 fetch_emit->draw = draw; 00410 00411 return &fetch_emit->base; 00412 }
static void fetch_emit_destroy | ( | struct draw_pt_middle_end * | middle | ) | [static] |
Definition at line 379 of file draw_pt_fetch_emit.c.
References fetch_emit_middle_end::cache, FREE, and translate_cache_destroy().
00380 { 00381 struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; 00382 00383 if (feme->cache) 00384 translate_cache_destroy(feme->cache); 00385 00386 FREE(middle); 00387 }
static void fetch_emit_finish | ( | struct draw_pt_middle_end * | middle | ) | [static] |
static void fetch_emit_prepare | ( | struct draw_pt_middle_end * | middle, | |
unsigned | prim, | |||
unsigned | opt, | |||
unsigned * | max_vertices | |||
) | [static] |
Definition at line 91 of file draw_pt_fetch_emit.c.
References assert, vertex_info::attrib, pipe_vertex_buffer::buffer_offset, fetch_emit_middle_end::cache, fetch_emit_middle_end::draw, draw, translate_key::element, vertex_info::emit, EMIT_1F, EMIT_1F_PSIZE, EMIT_2F, EMIT_3F, EMIT_4F, vbuf_render::get_vertex_info, translate_element::input_buffer, translate_element::input_format, translate_element::input_offset, translate::key, vbuf_render::max_vertex_buffer_bytes, translate_key::nr_elements, draw_context::nr_vertex_buffers, vertex_info::num_attribs, translate_element::output_format, translate_element::output_offset, translate_key::output_stride, PIPE_FORMAT_NONE, PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, pipe_vertex_buffer::pitch, pipe_rasterizer_state::point_size, fetch_emit_middle_end::point_size, draw_context::pt, draw_context::rasterizer, draw_context::render, translate::set_buffer, vbuf_render::set_primitive, vertex_info::size, pipe_vertex_element::src_format, vertex_info::src_index, pipe_vertex_element::src_offset, fetch_emit_middle_end::translate, translate_cache_find(), translate_key_compare(), translate_key_sanitize(), draw_context::user, draw_context::vertex_buffer, pipe_vertex_element::vertex_buffer_index, draw_context::vertex_element, and fetch_emit_middle_end::vinfo.
00095 { 00096 struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; 00097 struct draw_context *draw = feme->draw; 00098 const struct vertex_info *vinfo; 00099 unsigned i, dst_offset; 00100 boolean ok; 00101 struct translate_key key; 00102 00103 00104 ok = draw->render->set_primitive( draw->render, 00105 prim ); 00106 if (!ok) { 00107 assert(0); 00108 return; 00109 } 00110 00111 /* Must do this after set_primitive() above: 00112 */ 00113 vinfo = feme->vinfo = draw->render->get_vertex_info(draw->render); 00114 00115 00116 00117 /* Transform from API vertices to HW vertices, skipping the 00118 * pipeline_vertex intermediate step. 00119 */ 00120 dst_offset = 0; 00121 memset(&key, 0, sizeof(key)); 00122 00123 for (i = 0; i < vinfo->num_attribs; i++) { 00124 const struct pipe_vertex_element *src = &draw->pt.vertex_element[vinfo->attrib[i].src_index]; 00125 00126 unsigned emit_sz = 0; 00127 unsigned input_format = src->src_format; 00128 unsigned input_buffer = src->vertex_buffer_index; 00129 unsigned input_offset = src->src_offset; 00130 unsigned output_format; 00131 00132 switch (vinfo->attrib[i].emit) { 00133 case EMIT_4F: 00134 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 00135 emit_sz = 4 * sizeof(float); 00136 break; 00137 case EMIT_3F: 00138 output_format = PIPE_FORMAT_R32G32B32_FLOAT; 00139 emit_sz = 3 * sizeof(float); 00140 break; 00141 case EMIT_2F: 00142 output_format = PIPE_FORMAT_R32G32_FLOAT; 00143 emit_sz = 2 * sizeof(float); 00144 break; 00145 case EMIT_1F: 00146 output_format = PIPE_FORMAT_R32_FLOAT; 00147 emit_sz = 1 * sizeof(float); 00148 break; 00149 case EMIT_1F_PSIZE: 00150 input_format = PIPE_FORMAT_R32_FLOAT; 00151 input_buffer = draw->pt.nr_vertex_buffers; 00152 input_offset = 0; 00153 output_format = PIPE_FORMAT_R32_FLOAT; 00154 emit_sz = 1 * sizeof(float); 00155 break; 00156 default: 00157 assert(0); 00158 output_format = PIPE_FORMAT_NONE; 00159 emit_sz = 0; 00160 continue; 00161 } 00162 00163 key.element[i].input_format = input_format; 00164 key.element[i].input_buffer = input_buffer; 00165 key.element[i].input_offset = input_offset; 00166 key.element[i].output_format = output_format; 00167 key.element[i].output_offset = dst_offset; 00168 00169 dst_offset += emit_sz; 00170 } 00171 00172 key.nr_elements = vinfo->num_attribs; 00173 key.output_stride = vinfo->size * 4; 00174 00175 /* Don't bother with caching at this stage: 00176 */ 00177 if (!feme->translate || 00178 translate_key_compare(&feme->translate->key, &key) != 0) 00179 { 00180 translate_key_sanitize(&key); 00181 feme->translate = translate_cache_find(feme->cache, 00182 &key); 00183 00184 00185 feme->translate->set_buffer(feme->translate, 00186 draw->pt.nr_vertex_buffers, 00187 &feme->point_size, 00188 0); 00189 } 00190 00191 feme->point_size = draw->rasterizer->point_size; 00192 00193 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { 00194 feme->translate->set_buffer(feme->translate, 00195 i, 00196 ((char *)draw->pt.user.vbuffer[i] + 00197 draw->pt.vertex_buffer[i].buffer_offset), 00198 draw->pt.vertex_buffer[i].pitch ); 00199 } 00200 00201 *max_vertices = (draw->render->max_vertex_buffer_bytes / 00202 (vinfo->size * 4)); 00203 00204 /* Return an even number of verts. 00205 * This prevents "parity" errors when splitting long triangle strips which 00206 * can lead to front/back culling mix-ups. 00207 * Every other triangle in a strip has an alternate front/back orientation 00208 * so splitting at an odd position can cause the orientation of subsequent 00209 * triangles to get reversed. 00210 */ 00211 *max_vertices = *max_vertices & ~1; 00212 }
static void fetch_emit_run | ( | struct draw_pt_middle_end * | middle, | |
const unsigned * | fetch_elts, | |||
unsigned | fetch_count, | |||
const ushort * | draw_elts, | |||
unsigned | draw_count | |||
) | [static] |
Definition at line 218 of file draw_pt_fetch_emit.c.
References vbuf_render::allocate_vertices, assert, debug_printf(), vbuf_render::draw, fetch_emit_middle_end::draw, draw, draw_do_flush(), draw_dump_emitted_vertex(), DRAW_FLUSH_BACKEND, translate::key, translate_key::output_stride, vbuf_render::release_vertices, draw_context::render, vertex_info::size, fetch_emit_middle_end::translate, and fetch_emit_middle_end::vinfo.
00223 { 00224 struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; 00225 struct draw_context *draw = feme->draw; 00226 void *hw_verts; 00227 00228 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 00229 */ 00230 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 00231 00232 hw_verts = draw->render->allocate_vertices( draw->render, 00233 (ushort)feme->translate->key.output_stride, 00234 (ushort)fetch_count ); 00235 if (!hw_verts) { 00236 assert(0); 00237 return; 00238 } 00239 00240 00241 /* Single routine to fetch vertices and emit HW verts. 00242 */ 00243 feme->translate->run_elts( feme->translate, 00244 fetch_elts, 00245 fetch_count, 00246 hw_verts ); 00247 00248 if (0) { 00249 unsigned i; 00250 for (i = 0; i < fetch_count; i++) { 00251 debug_printf("\n\nvertex %d:\n", i); 00252 draw_dump_emitted_vertex( feme->vinfo, 00253 (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); 00254 } 00255 } 00256 00257 /* XXX: Draw arrays path to avoid re-emitting index list again and 00258 * again. 00259 */ 00260 draw->render->draw( draw->render, 00261 draw_elts, 00262 draw_count ); 00263 00264 /* Done -- that was easy, wasn't it: 00265 */ 00266 draw->render->release_vertices( draw->render, 00267 hw_verts, 00268 feme->translate->key.output_stride, 00269 fetch_count ); 00270 00271 }
static void fetch_emit_run_linear | ( | struct draw_pt_middle_end * | middle, | |
unsigned | start, | |||
unsigned | count | |||
) | [static] |
Definition at line 274 of file draw_pt_fetch_emit.c.
References vbuf_render::allocate_vertices, assert, debug_printf(), fetch_emit_middle_end::draw, draw, vbuf_render::draw_arrays, draw_do_flush(), draw_dump_emitted_vertex(), DRAW_FLUSH_BACKEND, translate::key, translate_key::output_stride, vbuf_render::release_vertices, draw_context::render, vertex_info::size, fetch_emit_middle_end::translate, and fetch_emit_middle_end::vinfo.
00277 { 00278 struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; 00279 struct draw_context *draw = feme->draw; 00280 void *hw_verts; 00281 00282 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 00283 */ 00284 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 00285 00286 hw_verts = draw->render->allocate_vertices( draw->render, 00287 (ushort)feme->translate->key.output_stride, 00288 (ushort)count ); 00289 if (!hw_verts) { 00290 assert(0); 00291 return; 00292 } 00293 00294 /* Single routine to fetch vertices and emit HW verts. 00295 */ 00296 feme->translate->run( feme->translate, 00297 start, 00298 count, 00299 hw_verts ); 00300 00301 if (0) { 00302 unsigned i; 00303 for (i = 0; i < count; i++) { 00304 debug_printf("\n\nvertex %d:\n", i); 00305 draw_dump_emitted_vertex( feme->vinfo, 00306 (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); 00307 } 00308 } 00309 00310 /* XXX: Draw arrays path to avoid re-emitting index list again and 00311 * again. 00312 */ 00313 draw->render->draw_arrays( draw->render, 00314 0, /*start*/ 00315 count ); 00316 00317 /* Done -- that was easy, wasn't it: 00318 */ 00319 draw->render->release_vertices( draw->render, 00320 hw_verts, 00321 feme->translate->key.output_stride, 00322 count ); 00323 00324 }
static boolean fetch_emit_run_linear_elts | ( | struct draw_pt_middle_end * | middle, | |
unsigned | start, | |||
unsigned | count, | |||
const ushort * | draw_elts, | |||
unsigned | draw_count | |||
) | [static] |
Definition at line 327 of file draw_pt_fetch_emit.c.
References vbuf_render::allocate_vertices, vbuf_render::draw, fetch_emit_middle_end::draw, draw, draw_do_flush(), DRAW_FLUSH_BACKEND, FALSE, translate::key, translate_key::output_stride, vbuf_render::release_vertices, draw_context::render, fetch_emit_middle_end::translate, and TRUE.
00332 { 00333 struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; 00334 struct draw_context *draw = feme->draw; 00335 void *hw_verts; 00336 00337 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 00338 */ 00339 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 00340 00341 hw_verts = draw->render->allocate_vertices( draw->render, 00342 (ushort)feme->translate->key.output_stride, 00343 (ushort)count ); 00344 if (!hw_verts) 00345 return FALSE; 00346 00347 /* Single routine to fetch vertices and emit HW verts. 00348 */ 00349 feme->translate->run( feme->translate, 00350 start, 00351 count, 00352 hw_verts ); 00353 00354 /* XXX: Draw arrays path to avoid re-emitting index list again and 00355 * again. 00356 */ 00357 draw->render->draw( draw->render, 00358 draw_elts, 00359 draw_count ); 00360 00361 /* Done -- that was easy, wasn't it: 00362 */ 00363 draw->render->release_vertices( draw->render, 00364 hw_verts, 00365 feme->translate->key.output_stride, 00366 count ); 00367 00368 return TRUE; 00369 }