draw_pt.c revision cd8614b0287dc5a69725ec4ee0208fad61f7789e
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Keith Whitwell <keith@tungstengraphics.com> 31 */ 32 33#include "draw/draw_context.h" 34#include "draw/draw_private.h" 35#include "draw/draw_pt.h" 36#include "tgsi/tgsi_dump.h" 37#include "util/u_math.h" 38#include "util/u_prim.h" 39 40static unsigned trim( unsigned count, unsigned first, unsigned incr ) 41{ 42 if (count < first) 43 return 0; 44 return count - (count - first) % incr; 45} 46 47 48 49/* Overall we split things into: 50 * - frontend -- prepare fetch_elts, draw_elts - eg vcache 51 * - middle -- fetch, shade, cliptest, viewport 52 * - pipeline -- the prim pipeline: clipping, wide lines, etc 53 * - backend -- the vbuf_render provided by the driver. 54 */ 55static boolean 56draw_pt_arrays(struct draw_context *draw, 57 unsigned prim, 58 unsigned start, 59 unsigned count) 60{ 61 struct draw_pt_front_end *frontend = NULL; 62 struct draw_pt_middle_end *middle = NULL; 63 unsigned opt = 0; 64 65 /* Sanitize primitive length: 66 */ 67 { 68 unsigned first, incr; 69 draw_pt_split_prim(prim, &first, &incr); 70 count = trim(count, first, incr); 71 if (count < first) 72 return TRUE; 73 } 74 75 if (!draw->force_passthrough) { 76 if (!draw->render) { 77 opt |= PT_PIPELINE; 78 } 79 80 if (draw_need_pipeline(draw, 81 draw->rasterizer, 82 prim)) { 83 opt |= PT_PIPELINE; 84 } 85 86 if (!draw->bypass_clipping && !draw->pt.test_fse) { 87 opt |= PT_CLIPTEST; 88 } 89 90 if (!draw->rasterizer->bypass_vs_clip_and_viewport) { 91 opt |= PT_SHADE; 92 } 93 } 94 95 if (opt == 0) 96 middle = draw->pt.middle.fetch_emit; 97 else if (opt == PT_SHADE && !draw->pt.no_fse) 98 middle = draw->pt.middle.fetch_shade_emit; 99 else 100 middle = draw->pt.middle.general; 101 102 103 /* Pick the right frontend 104 */ 105 if (draw->pt.user.elts || (opt & PT_PIPELINE)) { 106 frontend = draw->pt.front.vcache; 107 } else { 108 frontend = draw->pt.front.varray; 109 } 110 111 frontend->prepare( frontend, prim, middle, opt ); 112 113 frontend->run(frontend, 114 draw_pt_elt_func(draw), 115 draw_pt_elt_ptr(draw, start), 116 count); 117 118 frontend->finish( frontend ); 119 120 return TRUE; 121} 122 123 124boolean draw_pt_init( struct draw_context *draw ) 125{ 126 draw->pt.test_fse = debug_get_bool_option("DRAW_FSE", FALSE); 127 draw->pt.no_fse = debug_get_bool_option("DRAW_NO_FSE", FALSE); 128 129 draw->pt.front.vcache = draw_pt_vcache( draw ); 130 if (!draw->pt.front.vcache) 131 return FALSE; 132 133 draw->pt.front.varray = draw_pt_varray(draw); 134 if (!draw->pt.front.varray) 135 return FALSE; 136 137 draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); 138 if (!draw->pt.middle.fetch_emit) 139 return FALSE; 140 141 draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); 142 if (!draw->pt.middle.fetch_shade_emit) 143 return FALSE; 144 145 draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); 146 if (!draw->pt.middle.general) 147 return FALSE; 148 149 return TRUE; 150} 151 152 153void draw_pt_destroy( struct draw_context *draw ) 154{ 155 if (draw->pt.middle.general) { 156 draw->pt.middle.general->destroy( draw->pt.middle.general ); 157 draw->pt.middle.general = NULL; 158 } 159 160 if (draw->pt.middle.fetch_emit) { 161 draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); 162 draw->pt.middle.fetch_emit = NULL; 163 } 164 165 if (draw->pt.middle.fetch_shade_emit) { 166 draw->pt.middle.fetch_shade_emit->destroy( draw->pt.middle.fetch_shade_emit ); 167 draw->pt.middle.fetch_shade_emit = NULL; 168 } 169 170 if (draw->pt.front.vcache) { 171 draw->pt.front.vcache->destroy( draw->pt.front.vcache ); 172 draw->pt.front.vcache = NULL; 173 } 174 175 if (draw->pt.front.varray) { 176 draw->pt.front.varray->destroy( draw->pt.front.varray ); 177 draw->pt.front.varray = NULL; 178 } 179} 180 181 182/** 183 * Debug- print the first 'count' vertices. 184 */ 185static void 186draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count) 187{ 188 uint i; 189 190 debug_printf("Draw arrays(prim = %u, start = %u, count = %u)\n", 191 prim, start, count); 192 193 for (i = 0; i < count; i++) { 194 uint ii = 0; 195 uint j; 196 197 if (draw->pt.user.elts) { 198 /* indexed arrays */ 199 switch (draw->pt.user.eltSize) { 200 case 1: 201 { 202 const ubyte *elem = (const ubyte *) draw->pt.user.elts; 203 ii = elem[start + i]; 204 } 205 break; 206 case 2: 207 { 208 const ushort *elem = (const ushort *) draw->pt.user.elts; 209 ii = elem[start + i]; 210 } 211 break; 212 case 4: 213 { 214 const uint *elem = (const uint *) draw->pt.user.elts; 215 ii = elem[start + i]; 216 } 217 break; 218 default: 219 assert(0); 220 } 221 debug_printf("Element[%u + %u] -> Vertex %u:\n", start, i, ii); 222 } 223 else { 224 /* non-indexed arrays */ 225 ii = start + i; 226 debug_printf("Vertex %u:\n", ii); 227 } 228 229 for (j = 0; j < draw->pt.nr_vertex_elements; j++) { 230 uint buf = draw->pt.vertex_element[j].vertex_buffer_index; 231 ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; 232 ptr += draw->pt.vertex_buffer[buf].stride * ii; 233 ptr += draw->pt.vertex_element[j].src_offset; 234 235 debug_printf(" Attr %u: ", j); 236 switch (draw->pt.vertex_element[j].src_format) { 237 case PIPE_FORMAT_R32_FLOAT: 238 { 239 float *v = (float *) ptr; 240 debug_printf("%f @ %p\n", v[0], (void *) v); 241 } 242 break; 243 case PIPE_FORMAT_R32G32_FLOAT: 244 { 245 float *v = (float *) ptr; 246 debug_printf("%f %f @ %p\n", v[0], v[1], (void *) v); 247 } 248 break; 249 case PIPE_FORMAT_R32G32B32_FLOAT: 250 { 251 float *v = (float *) ptr; 252 debug_printf("%f %f %f @ %p\n", v[0], v[1], v[2], (void *) v); 253 } 254 break; 255 case PIPE_FORMAT_R32G32B32A32_FLOAT: 256 { 257 float *v = (float *) ptr; 258 debug_printf("%f %f %f %f @ %p\n", v[0], v[1], v[2], v[3], 259 (void *) v); 260 } 261 break; 262 default: 263 debug_printf("other format (fix me)\n"); 264 ; 265 } 266 } 267 } 268} 269 270 271/** 272 * Draw vertex arrays 273 * This is the main entrypoint into the drawing module. 274 * \param prim one of PIPE_PRIM_x 275 * \param start index of first vertex to draw 276 * \param count number of vertices to draw 277 */ 278void 279draw_arrays(struct draw_context *draw, unsigned prim, 280 unsigned start, unsigned count) 281{ 282 draw_arrays_instanced(draw, prim, start, count, 0, 1); 283} 284 285void 286draw_arrays_instanced(struct draw_context *draw, 287 unsigned mode, 288 unsigned start, 289 unsigned count, 290 unsigned startInstance, 291 unsigned instanceCount) 292{ 293 unsigned reduced_prim = u_reduced_prim(mode); 294 unsigned instance; 295 296 if (reduced_prim != draw->reduced_prim) { 297 draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); 298 draw->reduced_prim = reduced_prim; 299 } 300 301 if (0) 302 draw_print_arrays(draw, mode, start, MIN2(count, 20)); 303 304#if 0 305 { 306 int i; 307 debug_printf("draw_arrays(mode=%u start=%u count=%u):\n", 308 mode, start, count); 309 tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); 310 debug_printf("Elements:\n"); 311 for (i = 0; i < draw->pt.nr_vertex_elements; i++) { 312 debug_printf(" format=%s comps=%u\n", 313 pf_name(draw->pt.vertex_element[i].src_format), 314 draw->pt.vertex_element[i].nr_components); 315 } 316 debug_printf("Buffers:\n"); 317 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { 318 debug_printf(" stride=%u offset=%u ptr=%p\n", 319 draw->pt.vertex_buffer[i].stride, 320 draw->pt.vertex_buffer[i].buffer_offset, 321 draw->pt.user.vbuffer[i]); 322 } 323 } 324#endif 325 326 for (instance = 0; instance < instanceCount; instance++) { 327 draw->instance_id = instance + startInstance; 328 draw_pt_arrays(draw, mode, start, count); 329 } 330} 331