1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg /* 29848b8605Smrg * Authors: 30848b8605Smrg * Keith Whitwell <keithw@vmware.com> 31848b8605Smrg */ 32848b8605Smrg 33848b8605Smrg#include "draw/draw_context.h" 34848b8605Smrg#include "draw/draw_gs.h" 35848b8605Smrg#include "draw/draw_private.h" 36848b8605Smrg#include "draw/draw_pt.h" 37848b8605Smrg#include "draw/draw_vbuf.h" 38848b8605Smrg#include "draw/draw_vs.h" 39848b8605Smrg#include "tgsi/tgsi_dump.h" 40848b8605Smrg#include "util/u_math.h" 41848b8605Smrg#include "util/u_prim.h" 42848b8605Smrg#include "util/u_format.h" 43848b8605Smrg#include "util/u_draw.h" 44848b8605Smrg 45848b8605Smrg 46848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE) 47848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(draw_no_fse, "DRAW_NO_FSE", FALSE) 48848b8605Smrg 49848b8605Smrg/* Overall we split things into: 50848b8605Smrg * - frontend -- prepare fetch_elts, draw_elts - eg vsplit 51848b8605Smrg * - middle -- fetch, shade, cliptest, viewport 52848b8605Smrg * - pipeline -- the prim pipeline: clipping, wide lines, etc 53848b8605Smrg * - backend -- the vbuf_render provided by the driver. 54848b8605Smrg */ 55848b8605Smrgstatic boolean 56848b8605Smrgdraw_pt_arrays(struct draw_context *draw, 57848b8605Smrg unsigned prim, 58848b8605Smrg unsigned start, 59848b8605Smrg unsigned count) 60848b8605Smrg{ 61848b8605Smrg struct draw_pt_front_end *frontend = NULL; 62848b8605Smrg struct draw_pt_middle_end *middle = NULL; 63848b8605Smrg unsigned opt = 0; 64848b8605Smrg 65848b8605Smrg /* Sanitize primitive length: 66848b8605Smrg */ 67848b8605Smrg { 68848b8605Smrg unsigned first, incr; 69848b8605Smrg draw_pt_split_prim(prim, &first, &incr); 70848b8605Smrg count = draw_pt_trim_count(count, first, incr); 71848b8605Smrg if (count < first) 72848b8605Smrg return TRUE; 73848b8605Smrg } 74848b8605Smrg 75848b8605Smrg if (!draw->force_passthrough) { 76848b8605Smrg unsigned gs_out_prim = (draw->gs.geometry_shader ? 77848b8605Smrg draw->gs.geometry_shader->output_primitive : 78848b8605Smrg prim); 79848b8605Smrg 80848b8605Smrg if (!draw->render) { 81848b8605Smrg opt |= PT_PIPELINE; 82848b8605Smrg } 83848b8605Smrg 84848b8605Smrg if (draw_need_pipeline(draw, 85848b8605Smrg draw->rasterizer, 86848b8605Smrg gs_out_prim)) { 87848b8605Smrg opt |= PT_PIPELINE; 88848b8605Smrg } 89848b8605Smrg 90848b8605Smrg if ((draw->clip_xy || 91848b8605Smrg draw->clip_z || 92848b8605Smrg draw->clip_user) && !draw->pt.test_fse) { 93848b8605Smrg opt |= PT_CLIPTEST; 94848b8605Smrg } 95848b8605Smrg 96848b8605Smrg opt |= PT_SHADE; 97848b8605Smrg } 98848b8605Smrg 99848b8605Smrg if (draw->pt.middle.llvm) { 100848b8605Smrg middle = draw->pt.middle.llvm; 101848b8605Smrg } else { 102848b8605Smrg if (opt == 0) 103848b8605Smrg middle = draw->pt.middle.fetch_emit; 104848b8605Smrg else if (opt == PT_SHADE && !draw->pt.no_fse) 105848b8605Smrg middle = draw->pt.middle.fetch_shade_emit; 106848b8605Smrg else 107848b8605Smrg middle = draw->pt.middle.general; 108848b8605Smrg } 109848b8605Smrg 110848b8605Smrg frontend = draw->pt.frontend; 111848b8605Smrg 112b8e80941Smrg if (frontend) { 113848b8605Smrg if (draw->pt.prim != prim || draw->pt.opt != opt) { 114848b8605Smrg /* In certain conditions switching primitives requires us to flush 115848b8605Smrg * and validate the different stages. One example is when smooth 116848b8605Smrg * lines are active but first drawn with triangles and then with 117848b8605Smrg * lines. 118848b8605Smrg */ 119848b8605Smrg draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); 120848b8605Smrg frontend = NULL; 121848b8605Smrg } else if (draw->pt.eltSize != draw->pt.user.eltSize) { 122848b8605Smrg /* Flush draw state if eltSize changed. 123848b8605Smrg * This could be improved so only the frontend is flushed since it 124848b8605Smrg * converts all indices to ushorts and the fetch part of the middle 125848b8605Smrg * always prepares both linear and indexed. 126848b8605Smrg */ 127848b8605Smrg frontend->flush( frontend, DRAW_FLUSH_STATE_CHANGE ); 128848b8605Smrg frontend = NULL; 129848b8605Smrg } 130848b8605Smrg } 131848b8605Smrg 132848b8605Smrg if (!frontend) { 133848b8605Smrg frontend = draw->pt.front.vsplit; 134848b8605Smrg 135848b8605Smrg frontend->prepare( frontend, prim, middle, opt ); 136848b8605Smrg 137848b8605Smrg draw->pt.frontend = frontend; 138848b8605Smrg draw->pt.eltSize = draw->pt.user.eltSize; 139848b8605Smrg draw->pt.prim = prim; 140848b8605Smrg draw->pt.opt = opt; 141848b8605Smrg } 142848b8605Smrg 143848b8605Smrg if (draw->pt.rebind_parameters) { 144848b8605Smrg /* update constants, viewport dims, clip planes, etc */ 145848b8605Smrg middle->bind_parameters(middle); 146848b8605Smrg draw->pt.rebind_parameters = FALSE; 147848b8605Smrg } 148848b8605Smrg 149848b8605Smrg frontend->run( frontend, start, count ); 150848b8605Smrg 151848b8605Smrg return TRUE; 152848b8605Smrg} 153848b8605Smrg 154848b8605Smrgvoid draw_pt_flush( struct draw_context *draw, unsigned flags ) 155848b8605Smrg{ 156848b8605Smrg assert(flags); 157848b8605Smrg 158848b8605Smrg if (draw->pt.frontend) { 159848b8605Smrg draw->pt.frontend->flush( draw->pt.frontend, flags ); 160848b8605Smrg 161848b8605Smrg /* don't prepare if we only are flushing the backend */ 162848b8605Smrg if (flags & DRAW_FLUSH_STATE_CHANGE) 163848b8605Smrg draw->pt.frontend = NULL; 164848b8605Smrg } 165848b8605Smrg 166848b8605Smrg if (flags & DRAW_FLUSH_PARAMETER_CHANGE) { 167848b8605Smrg draw->pt.rebind_parameters = TRUE; 168848b8605Smrg } 169848b8605Smrg} 170848b8605Smrg 171848b8605Smrg 172848b8605Smrg 173848b8605Smrgboolean draw_pt_init( struct draw_context *draw ) 174848b8605Smrg{ 175848b8605Smrg draw->pt.test_fse = debug_get_option_draw_fse(); 176848b8605Smrg draw->pt.no_fse = debug_get_option_draw_no_fse(); 177848b8605Smrg 178848b8605Smrg draw->pt.front.vsplit = draw_pt_vsplit(draw); 179848b8605Smrg if (!draw->pt.front.vsplit) 180848b8605Smrg return FALSE; 181848b8605Smrg 182848b8605Smrg draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); 183848b8605Smrg if (!draw->pt.middle.fetch_emit) 184848b8605Smrg return FALSE; 185848b8605Smrg 186848b8605Smrg draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); 187848b8605Smrg if (!draw->pt.middle.fetch_shade_emit) 188848b8605Smrg return FALSE; 189848b8605Smrg 190848b8605Smrg draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); 191848b8605Smrg if (!draw->pt.middle.general) 192848b8605Smrg return FALSE; 193848b8605Smrg 194848b8605Smrg#if HAVE_LLVM 195848b8605Smrg if (draw->llvm) 196848b8605Smrg draw->pt.middle.llvm = draw_pt_fetch_pipeline_or_emit_llvm( draw ); 197848b8605Smrg#endif 198848b8605Smrg 199848b8605Smrg return TRUE; 200848b8605Smrg} 201848b8605Smrg 202848b8605Smrg 203848b8605Smrgvoid draw_pt_destroy( struct draw_context *draw ) 204848b8605Smrg{ 205848b8605Smrg if (draw->pt.middle.llvm) { 206848b8605Smrg draw->pt.middle.llvm->destroy( draw->pt.middle.llvm ); 207848b8605Smrg draw->pt.middle.llvm = NULL; 208848b8605Smrg } 209848b8605Smrg 210848b8605Smrg if (draw->pt.middle.general) { 211848b8605Smrg draw->pt.middle.general->destroy( draw->pt.middle.general ); 212848b8605Smrg draw->pt.middle.general = NULL; 213848b8605Smrg } 214848b8605Smrg 215848b8605Smrg if (draw->pt.middle.fetch_emit) { 216848b8605Smrg draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); 217848b8605Smrg draw->pt.middle.fetch_emit = NULL; 218848b8605Smrg } 219848b8605Smrg 220848b8605Smrg if (draw->pt.middle.fetch_shade_emit) { 221848b8605Smrg draw->pt.middle.fetch_shade_emit->destroy( draw->pt.middle.fetch_shade_emit ); 222848b8605Smrg draw->pt.middle.fetch_shade_emit = NULL; 223848b8605Smrg } 224848b8605Smrg 225848b8605Smrg if (draw->pt.front.vsplit) { 226848b8605Smrg draw->pt.front.vsplit->destroy( draw->pt.front.vsplit ); 227848b8605Smrg draw->pt.front.vsplit = NULL; 228848b8605Smrg } 229848b8605Smrg} 230848b8605Smrg 231848b8605Smrg 232848b8605Smrg/** 233848b8605Smrg * Debug- print the first 'count' vertices. 234848b8605Smrg */ 235848b8605Smrgstatic void 236848b8605Smrgdraw_print_arrays(struct draw_context *draw, uint prim, int start, uint count) 237848b8605Smrg{ 238848b8605Smrg uint i; 239848b8605Smrg 240848b8605Smrg debug_printf("Draw arrays(prim = %u, start = %u, count = %u)\n", 241848b8605Smrg prim, start, count); 242848b8605Smrg 243848b8605Smrg for (i = 0; i < count; i++) { 244848b8605Smrg uint ii = 0; 245848b8605Smrg uint j; 246848b8605Smrg 247848b8605Smrg if (draw->pt.user.eltSize) { 248848b8605Smrg /* indexed arrays */ 249848b8605Smrg 250848b8605Smrg switch (draw->pt.user.eltSize) { 251848b8605Smrg case 1: 252848b8605Smrg { 253848b8605Smrg const ubyte *elem = (const ubyte *) draw->pt.user.elts; 254848b8605Smrg ii = elem[start + i]; 255848b8605Smrg } 256848b8605Smrg break; 257848b8605Smrg case 2: 258848b8605Smrg { 259848b8605Smrg const ushort *elem = (const ushort *) draw->pt.user.elts; 260848b8605Smrg ii = elem[start + i]; 261848b8605Smrg } 262848b8605Smrg break; 263848b8605Smrg case 4: 264848b8605Smrg { 265848b8605Smrg const uint *elem = (const uint *) draw->pt.user.elts; 266848b8605Smrg ii = elem[start + i]; 267848b8605Smrg } 268848b8605Smrg break; 269848b8605Smrg default: 270848b8605Smrg assert(0); 271848b8605Smrg return; 272848b8605Smrg } 273848b8605Smrg ii += draw->pt.user.eltBias; 274848b8605Smrg debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i, 275848b8605Smrg draw->pt.user.eltBias, ii); 276848b8605Smrg } 277848b8605Smrg else { 278848b8605Smrg /* non-indexed arrays */ 279848b8605Smrg ii = start + i; 280848b8605Smrg debug_printf("Vertex %u:\n", ii); 281848b8605Smrg } 282848b8605Smrg 283848b8605Smrg for (j = 0; j < draw->pt.nr_vertex_elements; j++) { 284848b8605Smrg uint buf = draw->pt.vertex_element[j].vertex_buffer_index; 285848b8605Smrg ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf].map; 286848b8605Smrg 287848b8605Smrg if (draw->pt.vertex_element[j].instance_divisor) { 288848b8605Smrg ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor; 289848b8605Smrg } 290848b8605Smrg 291848b8605Smrg ptr += draw->pt.vertex_buffer[buf].buffer_offset; 292848b8605Smrg ptr += draw->pt.vertex_buffer[buf].stride * ii; 293848b8605Smrg ptr += draw->pt.vertex_element[j].src_offset; 294848b8605Smrg 295848b8605Smrg debug_printf(" Attr %u: ", j); 296848b8605Smrg switch (draw->pt.vertex_element[j].src_format) { 297848b8605Smrg case PIPE_FORMAT_R32_FLOAT: 298848b8605Smrg { 299848b8605Smrg float *v = (float *) ptr; 300848b8605Smrg debug_printf("R %f @ %p\n", v[0], (void *) v); 301848b8605Smrg } 302848b8605Smrg break; 303848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: 304848b8605Smrg { 305848b8605Smrg float *v = (float *) ptr; 306848b8605Smrg debug_printf("RG %f %f @ %p\n", v[0], v[1], (void *) v); 307848b8605Smrg } 308848b8605Smrg break; 309848b8605Smrg case PIPE_FORMAT_R32G32B32_FLOAT: 310848b8605Smrg { 311848b8605Smrg float *v = (float *) ptr; 312848b8605Smrg debug_printf("RGB %f %f %f @ %p\n", v[0], v[1], v[2], (void *) v); 313848b8605Smrg } 314848b8605Smrg break; 315848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 316848b8605Smrg { 317848b8605Smrg float *v = (float *) ptr; 318848b8605Smrg debug_printf("RGBA %f %f %f %f @ %p\n", v[0], v[1], v[2], v[3], 319848b8605Smrg (void *) v); 320848b8605Smrg } 321848b8605Smrg break; 322848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 323848b8605Smrg { 324848b8605Smrg ubyte *u = (ubyte *) ptr; 325848b8605Smrg debug_printf("BGRA %d %d %d %d @ %p\n", u[0], u[1], u[2], u[3], 326848b8605Smrg (void *) u); 327848b8605Smrg } 328848b8605Smrg break; 329848b8605Smrg case PIPE_FORMAT_A8R8G8B8_UNORM: 330848b8605Smrg { 331848b8605Smrg ubyte *u = (ubyte *) ptr; 332848b8605Smrg debug_printf("ARGB %d %d %d %d @ %p\n", u[0], u[1], u[2], u[3], 333848b8605Smrg (void *) u); 334848b8605Smrg } 335848b8605Smrg break; 336848b8605Smrg default: 337848b8605Smrg debug_printf("other format %s (fix me)\n", 338848b8605Smrg util_format_name(draw->pt.vertex_element[j].src_format)); 339848b8605Smrg } 340848b8605Smrg } 341848b8605Smrg } 342848b8605Smrg} 343848b8605Smrg 344848b8605Smrg 345848b8605Smrg/** Helper code for below */ 346848b8605Smrg#define PRIM_RESTART_LOOP(elements) \ 347848b8605Smrg do { \ 348848b8605Smrg for (j = 0; j < count; j++) { \ 349848b8605Smrg i = draw_overflow_uadd(start, j, MAX_LOOP_IDX); \ 350848b8605Smrg if (i < elt_max && elements[i] == info->restart_index) { \ 351848b8605Smrg if (cur_count > 0) { \ 352848b8605Smrg /* draw elts up to prev pos */ \ 353848b8605Smrg draw_pt_arrays(draw, prim, cur_start, cur_count); \ 354848b8605Smrg } \ 355848b8605Smrg /* begin new prim at next elt */ \ 356848b8605Smrg cur_start = i + 1; \ 357848b8605Smrg cur_count = 0; \ 358848b8605Smrg } \ 359848b8605Smrg else { \ 360848b8605Smrg cur_count++; \ 361848b8605Smrg } \ 362848b8605Smrg } \ 363848b8605Smrg if (cur_count > 0) { \ 364848b8605Smrg draw_pt_arrays(draw, prim, cur_start, cur_count); \ 365848b8605Smrg } \ 366848b8605Smrg } while (0) 367848b8605Smrg 368848b8605Smrg 369848b8605Smrg/** 370848b8605Smrg * For drawing prims with primitive restart enabled. 371848b8605Smrg * Scan for restart indexes and draw the runs of elements/vertices between 372848b8605Smrg * the restarts. 373848b8605Smrg */ 374848b8605Smrgstatic void 375848b8605Smrgdraw_pt_arrays_restart(struct draw_context *draw, 376848b8605Smrg const struct pipe_draw_info *info) 377848b8605Smrg{ 378848b8605Smrg const unsigned prim = info->mode; 379848b8605Smrg const unsigned start = info->start; 380848b8605Smrg const unsigned count = info->count; 381848b8605Smrg const unsigned elt_max = draw->pt.user.eltMax; 382848b8605Smrg unsigned i, j, cur_start, cur_count; 383848b8605Smrg /* The largest index within a loop using the i variable as the index. 384848b8605Smrg * Used for overflow detection */ 385848b8605Smrg const unsigned MAX_LOOP_IDX = 0xffffffff; 386848b8605Smrg 387848b8605Smrg assert(info->primitive_restart); 388848b8605Smrg 389848b8605Smrg if (draw->pt.user.eltSize) { 390848b8605Smrg /* indexed prims (draw_elements) */ 391848b8605Smrg cur_start = start; 392848b8605Smrg cur_count = 0; 393848b8605Smrg 394848b8605Smrg switch (draw->pt.user.eltSize) { 395848b8605Smrg case 1: 396848b8605Smrg { 397848b8605Smrg const ubyte *elt_ub = (const ubyte *) draw->pt.user.elts; 398848b8605Smrg PRIM_RESTART_LOOP(elt_ub); 399848b8605Smrg } 400848b8605Smrg break; 401848b8605Smrg case 2: 402848b8605Smrg { 403848b8605Smrg const ushort *elt_us = (const ushort *) draw->pt.user.elts; 404848b8605Smrg PRIM_RESTART_LOOP(elt_us); 405848b8605Smrg } 406848b8605Smrg break; 407848b8605Smrg case 4: 408848b8605Smrg { 409848b8605Smrg const uint *elt_ui = (const uint *) draw->pt.user.elts; 410848b8605Smrg PRIM_RESTART_LOOP(elt_ui); 411848b8605Smrg } 412848b8605Smrg break; 413848b8605Smrg default: 414848b8605Smrg assert(0 && "bad eltSize in draw_arrays()"); 415848b8605Smrg } 416848b8605Smrg } 417848b8605Smrg else { 418848b8605Smrg /* Non-indexed prims (draw_arrays). 419848b8605Smrg * Primitive restart should have been handled in the state tracker. 420848b8605Smrg */ 421848b8605Smrg draw_pt_arrays(draw, prim, start, count); 422848b8605Smrg } 423848b8605Smrg} 424848b8605Smrg 425848b8605Smrg 426848b8605Smrg/** 427848b8605Smrg * Resolve true values within pipe_draw_info. 428848b8605Smrg * If we're rendering from transform feedback/stream output 429848b8605Smrg * buffers both the count and max_index need to be computed 430848b8605Smrg * from the attached stream output target. 431848b8605Smrg */ 432848b8605Smrgstatic void 433848b8605Smrgresolve_draw_info(const struct pipe_draw_info *raw_info, 434848b8605Smrg struct pipe_draw_info *info, 435848b8605Smrg struct pipe_vertex_buffer *vertex_buffer) 436848b8605Smrg{ 437848b8605Smrg memcpy(info, raw_info, sizeof(struct pipe_draw_info)); 438848b8605Smrg 439848b8605Smrg if (raw_info->count_from_stream_output) { 440848b8605Smrg struct draw_so_target *target = 441848b8605Smrg (struct draw_so_target *)info->count_from_stream_output; 442848b8605Smrg assert(vertex_buffer != NULL); 443848b8605Smrg info->count = target->internal_offset / vertex_buffer->stride; 444848b8605Smrg 445848b8605Smrg /* Stream output draw can not be indexed */ 446b8e80941Smrg debug_assert(!info->index_size); 447848b8605Smrg info->max_index = info->count - 1; 448848b8605Smrg } 449848b8605Smrg} 450848b8605Smrg 451848b8605Smrg/** 452848b8605Smrg * Draw vertex arrays. 453848b8605Smrg * This is the main entrypoint into the drawing module. If drawing an indexed 454848b8605Smrg * primitive, the draw_set_indexes() function should have already been called 455848b8605Smrg * to specify the element/index buffer information. 456848b8605Smrg */ 457848b8605Smrgvoid 458848b8605Smrgdraw_vbo(struct draw_context *draw, 459848b8605Smrg const struct pipe_draw_info *info) 460848b8605Smrg{ 461848b8605Smrg unsigned instance; 462848b8605Smrg unsigned index_limit; 463848b8605Smrg unsigned count; 464848b8605Smrg unsigned fpstate = util_fpstate_get(); 465848b8605Smrg struct pipe_draw_info resolved_info; 466848b8605Smrg 467b8e80941Smrg if (info->instance_count == 0) 468b8e80941Smrg return; 469b8e80941Smrg 470848b8605Smrg /* Make sure that denorms are treated like zeros. This is 471848b8605Smrg * the behavior required by D3D10. OpenGL doesn't care. 472848b8605Smrg */ 473848b8605Smrg util_fpstate_set_denorms_to_zero(fpstate); 474848b8605Smrg 475848b8605Smrg resolve_draw_info(info, &resolved_info, &(draw->pt.vertex_buffer[0])); 476848b8605Smrg info = &resolved_info; 477848b8605Smrg 478b8e80941Smrg if (info->index_size) 479848b8605Smrg assert(draw->pt.user.elts); 480848b8605Smrg 481848b8605Smrg count = info->count; 482848b8605Smrg 483848b8605Smrg draw->pt.user.eltBias = info->index_bias; 484848b8605Smrg draw->pt.user.min_index = info->min_index; 485848b8605Smrg draw->pt.user.max_index = info->max_index; 486b8e80941Smrg draw->pt.user.eltSize = info->index_size ? draw->pt.user.eltSizeIB : 0; 487848b8605Smrg 488848b8605Smrg if (0) 489848b8605Smrg debug_printf("draw_vbo(mode=%u start=%u count=%u):\n", 490848b8605Smrg info->mode, info->start, count); 491848b8605Smrg 492848b8605Smrg if (0) 493848b8605Smrg tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); 494848b8605Smrg 495848b8605Smrg if (0) { 496848b8605Smrg unsigned int i; 497848b8605Smrg debug_printf("Elements:\n"); 498848b8605Smrg for (i = 0; i < draw->pt.nr_vertex_elements; i++) { 499848b8605Smrg debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", 500848b8605Smrg i, 501848b8605Smrg draw->pt.vertex_element[i].src_offset, 502848b8605Smrg draw->pt.vertex_element[i].instance_divisor, 503848b8605Smrg draw->pt.vertex_element[i].vertex_buffer_index, 504848b8605Smrg util_format_name(draw->pt.vertex_element[i].src_format)); 505848b8605Smrg } 506848b8605Smrg debug_printf("Buffers:\n"); 507848b8605Smrg for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { 508848b8605Smrg debug_printf(" %u: stride=%u offset=%u size=%d ptr=%p\n", 509848b8605Smrg i, 510848b8605Smrg draw->pt.vertex_buffer[i].stride, 511848b8605Smrg draw->pt.vertex_buffer[i].buffer_offset, 512848b8605Smrg (int) draw->pt.user.vbuffer[i].size, 513848b8605Smrg draw->pt.user.vbuffer[i].map); 514848b8605Smrg } 515848b8605Smrg } 516848b8605Smrg 517848b8605Smrg if (0) 518848b8605Smrg draw_print_arrays(draw, info->mode, info->start, MIN2(count, 20)); 519848b8605Smrg 520848b8605Smrg index_limit = util_draw_max_index(draw->pt.vertex_buffer, 521848b8605Smrg draw->pt.vertex_element, 522848b8605Smrg draw->pt.nr_vertex_elements, 523848b8605Smrg info); 524848b8605Smrg#if HAVE_LLVM 525848b8605Smrg if (!draw->llvm) 526848b8605Smrg#endif 527848b8605Smrg { 528848b8605Smrg if (index_limit == 0) { 529b8e80941Smrg /* one of the buffers is too small to do any valid drawing */ 530848b8605Smrg debug_warning("draw: VBO too small to draw anything\n"); 531848b8605Smrg util_fpstate_set(fpstate); 532848b8605Smrg return; 533848b8605Smrg } 534848b8605Smrg } 535848b8605Smrg 536848b8605Smrg /* If we're collecting stats then make sure we start from scratch */ 537848b8605Smrg if (draw->collect_statistics) { 538848b8605Smrg memset(&draw->statistics, 0, sizeof(draw->statistics)); 539848b8605Smrg } 540848b8605Smrg 541848b8605Smrg draw->pt.max_index = index_limit - 1; 542848b8605Smrg draw->start_index = info->start; 543848b8605Smrg 544848b8605Smrg /* 545848b8605Smrg * TODO: We could use draw->pt.max_index to further narrow 546848b8605Smrg * the min_index/max_index hints given by the state tracker. 547848b8605Smrg */ 548848b8605Smrg 549848b8605Smrg for (instance = 0; instance < info->instance_count; instance++) { 550848b8605Smrg unsigned instance_idx = instance + info->start_instance; 551848b8605Smrg draw->start_instance = info->start_instance; 552848b8605Smrg draw->instance_id = instance; 553848b8605Smrg /* check for overflow */ 554848b8605Smrg if (instance_idx < instance || 555848b8605Smrg instance_idx < draw->start_instance) { 556848b8605Smrg /* if we overflown just set the instance id to the max */ 557848b8605Smrg draw->instance_id = 0xffffffff; 558848b8605Smrg } 559848b8605Smrg 560848b8605Smrg draw_new_instance(draw); 561848b8605Smrg 562848b8605Smrg if (info->primitive_restart) { 563848b8605Smrg draw_pt_arrays_restart(draw, info); 564848b8605Smrg } 565848b8605Smrg else { 566848b8605Smrg draw_pt_arrays(draw, info->mode, info->start, count); 567848b8605Smrg } 568848b8605Smrg } 569848b8605Smrg 570848b8605Smrg /* If requested emit the pipeline statistics for this run */ 571848b8605Smrg if (draw->collect_statistics) { 572848b8605Smrg draw->render->pipeline_statistics(draw->render, &draw->statistics); 573848b8605Smrg } 574848b8605Smrg util_fpstate_set(fpstate); 575848b8605Smrg} 576