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 #include "draw/draw_context.h"
00034 #include "draw/draw_private.h"
00035 #include "draw/draw_pt.h"
00036 #include "draw/draw_vs.h"
00037 #include "tgsi/tgsi_dump.h"
00038 #include "util/u_math.h"
00039 
00040 static unsigned trim( unsigned count, unsigned first, unsigned incr )
00041 {
00042    if (count < first)
00043       return 0;
00044    return count - (count - first) % incr; 
00045 }
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 static boolean
00056 draw_pt_arrays(struct draw_context *draw, 
00057                unsigned prim,
00058                unsigned start, 
00059                unsigned count)
00060 {
00061    struct draw_pt_front_end *frontend = NULL;
00062    struct draw_pt_middle_end *middle = NULL;
00063    unsigned opt = 0;
00064 
00065    
00066 
00067    {
00068       unsigned first, incr;
00069       draw_pt_split_prim(prim, &first, &incr);
00070       count = trim(count, first, incr); 
00071       if (count < first)
00072          return TRUE;
00073    }
00074 
00075    if (!draw->force_passthrough) {
00076       if (!draw->render) {
00077          opt |= PT_PIPELINE;
00078       }
00079       
00080       if (draw_need_pipeline(draw,
00081                              draw->rasterizer,
00082                              prim)) {
00083          opt |= PT_PIPELINE;
00084       }
00085 
00086       if (!draw->bypass_clipping && !draw->pt.test_fse) {
00087          opt |= PT_CLIPTEST;
00088       }
00089       
00090       if (!draw->rasterizer->bypass_vs) {
00091          opt |= PT_SHADE;
00092       }
00093    }
00094       
00095    if (opt == 0) 
00096       middle = draw->pt.middle.fetch_emit;
00097    else if (opt == PT_SHADE && !draw->pt.no_fse)
00098       middle = draw->pt.middle.fetch_shade_emit;
00099    else
00100       middle = draw->pt.middle.general;
00101 
00102 
00103    
00104 
00105    if (draw->pt.user.elts || (opt & PT_PIPELINE)) {
00106       frontend = draw->pt.front.vcache;
00107    } else {
00108       frontend = draw->pt.front.varray;
00109    }
00110 
00111    frontend->prepare( frontend, prim, middle, opt );
00112 
00113    frontend->run(frontend, 
00114                  draw_pt_elt_func(draw),
00115                  draw_pt_elt_ptr(draw, start),
00116                  count);
00117 
00118    frontend->finish( frontend );
00119 
00120    return TRUE;
00121 }
00122 
00123 
00124 boolean draw_pt_init( struct draw_context *draw )
00125 {
00126    draw->pt.test_fse = debug_get_bool_option("DRAW_FSE", FALSE);
00127    draw->pt.no_fse = debug_get_bool_option("DRAW_NO_FSE", FALSE);
00128 
00129    draw->pt.front.vcache = draw_pt_vcache( draw );
00130    if (!draw->pt.front.vcache)
00131       return FALSE;
00132 
00133    draw->pt.front.varray = draw_pt_varray(draw);
00134    if (!draw->pt.front.varray)
00135       return FALSE;
00136 
00137    draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw );
00138    if (!draw->pt.middle.fetch_emit)
00139       return FALSE;
00140 
00141    draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw );
00142    if (!draw->pt.middle.fetch_shade_emit)
00143       return FALSE;
00144 
00145    draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw );
00146    if (!draw->pt.middle.general)
00147       return FALSE;
00148 
00149    return TRUE;
00150 }
00151 
00152 
00153 void draw_pt_destroy( struct draw_context *draw )
00154 {
00155    if (draw->pt.middle.general) {
00156       draw->pt.middle.general->destroy( draw->pt.middle.general );
00157       draw->pt.middle.general = NULL;
00158    }
00159 
00160    if (draw->pt.middle.fetch_emit) {
00161       draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit );
00162       draw->pt.middle.fetch_emit = NULL;
00163    }
00164 
00165    if (draw->pt.middle.fetch_shade_emit) {
00166       draw->pt.middle.fetch_shade_emit->destroy( draw->pt.middle.fetch_shade_emit );
00167       draw->pt.middle.fetch_shade_emit = NULL;
00168    }
00169 
00170    if (draw->pt.front.vcache) {
00171       draw->pt.front.vcache->destroy( draw->pt.front.vcache );
00172       draw->pt.front.vcache = NULL;
00173    }
00174 
00175    if (draw->pt.front.varray) {
00176       draw->pt.front.varray->destroy( draw->pt.front.varray );
00177       draw->pt.front.varray = NULL;
00178    }
00179 }
00180 
00181 
00185 static void
00186 draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
00187 {
00188    uint i;
00189 
00190    debug_printf("Draw arrays(prim = %u, start = %u, count = %u)\n",
00191                 prim, start, count);
00192 
00193    for (i = 0; i < count; i++) {
00194       uint ii, j;
00195 
00196       if (draw->pt.user.elts) {
00197          
00198          switch (draw->pt.user.eltSize) {
00199          case 1:
00200             {
00201                const ubyte *elem = (const ubyte *) draw->pt.user.elts;
00202                ii = elem[start + i];
00203             }
00204             break;
00205          case 2:
00206             {
00207                const ushort *elem = (const ushort *) draw->pt.user.elts;
00208                ii = elem[start + i];
00209             }
00210             break;
00211          case 4:
00212             {
00213                const uint *elem = (const uint *) draw->pt.user.elts;
00214                ii = elem[start + i];
00215             }
00216             break;
00217          default:
00218             assert(0);
00219          }
00220          debug_printf("Element[%u + %u] -> Vertex %u:\n", start, i, ii);
00221       }
00222       else {
00223          
00224          ii = start + i;
00225          debug_printf("Vertex %u:\n", ii);
00226       }
00227 
00228       for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
00229          uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
00230          ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf];
00231          ptr += draw->pt.vertex_buffer[buf].pitch * ii;
00232          ptr += draw->pt.vertex_element[j].src_offset;
00233 
00234          debug_printf("  Attr %u: ", j);
00235          switch (draw->pt.vertex_element[j].src_format) {
00236          case PIPE_FORMAT_R32_FLOAT:
00237             {
00238                float *v = (float *) ptr;
00239                debug_printf("%f  @ %p\n", v[0], (void *) v);
00240             }
00241             break;
00242          case PIPE_FORMAT_R32G32_FLOAT:
00243             {
00244                float *v = (float *) ptr;
00245                debug_printf("%f %f  @ %p\n", v[0], v[1], (void *) v);
00246             }
00247             break;
00248          case PIPE_FORMAT_R32G32B32_FLOAT:
00249             {
00250                float *v = (float *) ptr;
00251                debug_printf("%f %f %f  @ %p\n", v[0], v[1], v[2], (void *) v);
00252             }
00253             break;
00254          case PIPE_FORMAT_R32G32B32A32_FLOAT:
00255             {
00256                float *v = (float *) ptr;
00257                debug_printf("%f %f %f %f  @ %p\n", v[0], v[1], v[2], v[3],
00258                             (void *) v);
00259             }
00260             break;
00261          default:
00262             debug_printf("other format (fix me)\n");
00263             ;
00264          }
00265       }
00266    }
00267 }
00268 
00269 
00277 void
00278 draw_arrays(struct draw_context *draw, unsigned prim,
00279             unsigned start, unsigned count)
00280 {
00281    unsigned reduced_prim = draw_pt_reduced_prim(prim);
00282    if (reduced_prim != draw->reduced_prim) {
00283       draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00284       draw->reduced_prim = reduced_prim;
00285    }
00286 
00287    if (0)
00288       draw_print_arrays(draw, prim, start, MIN2(count, 20));
00289 
00290 #if 0
00291    {
00292       int i;
00293       debug_printf("draw_arrays(prim=%u start=%u count=%u):\n",
00294                    prim, start, count);
00295       tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
00296       debug_printf("Elements:\n");
00297       for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
00298          debug_printf("  format=%s comps=%u\n",
00299                       pf_name(draw->pt.vertex_element[i].src_format),
00300                       draw->pt.vertex_element[i].nr_components);
00301       }
00302       debug_printf("Buffers:\n");
00303       for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00304          debug_printf("  pitch=%u offset=%u ptr=%p\n",
00305                       draw->pt.vertex_buffer[i].pitch,
00306                       draw->pt.vertex_buffer[i].buffer_offset,
00307                       draw->pt.user.vbuffer[i]);
00308       }
00309    }
00310 #endif
00311 
00312    
00313    draw_pt_arrays(draw, prim, start, count);
00314 }
00315 
00316 boolean draw_pt_get_edgeflag( struct draw_context *draw,
00317                               unsigned idx )
00318 {
00319    if (draw->pt.user.edgeflag)
00320       return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
00321    else
00322       return 1;
00323 }