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 }