draw_pt_fetch_emit.c File Reference

Include dependency graph for draw_pt_fetch_emit.c:

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_enddraw_pt_fetch_emit (struct draw_context *draw)


Function Documentation

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]

Definition at line 374 of file draw_pt_fetch_emit.c.

00375 {
00376    /* nothing to do */
00377 }

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 }


Generated on Tue Sep 29 06:25:21 2009 for Gallium3D by  doxygen 1.5.4