/** * Draw vertex arrays * This is the main entrypoint into the drawing module. * \param prim one of PIPE_PRIM_x * \param start index of first vertex to draw * \param count number of vertices to draw */ void draw_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count) { unsigned reduced_prim = draw_pt_reduced_prim(prim); if (reduced_prim != draw->reduced_prim) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->reduced_prim = reduced_prim; } /* drawing done here: */ draw_pt_arrays(draw, prim, start, count); }
/** * For drawing prims with primitive restart enabled. * Scan for restart indexes and draw the runs of elements/vertices between * the restarts. */ static void draw_pt_arrays_restart(struct draw_context *draw, const struct pipe_draw_info *info) { const unsigned prim = info->mode; const unsigned start = info->start; const unsigned count = info->count; const unsigned end = start + count; unsigned i, cur_start, cur_count; assert(info->primitive_restart); if (draw->pt.user.elts) { /* indexed prims (draw_elements) */ cur_start = start; cur_count = 0; switch (draw->pt.user.eltSize) { case 1: { const ubyte *elt_ub = (const ubyte *) draw->pt.user.elts; PRIM_RESTART_LOOP(elt_ub); } break; case 2: { const ushort *elt_us = (const ushort *) draw->pt.user.elts; PRIM_RESTART_LOOP(elt_us); } break; case 4: { const uint *elt_ui = (const uint *) draw->pt.user.elts; PRIM_RESTART_LOOP(elt_ui); } break; default: assert(0 && "bad eltSize in draw_arrays()"); } } else { /* Non-indexed prims (draw_arrays). * Primitive restart should have been handled in the state tracker. */ draw_pt_arrays(draw, prim, start, count); } }
/** * Draw vertex arrays. * This is the main entrypoint into the drawing module. If drawing an indexed * primitive, the draw_set_index_buffer() and draw_set_mapped_index_buffer() * functions should have already been called to specify the element/index * buffer information. */ void draw_vbo(struct draw_context *draw, const struct pipe_draw_info *info) { unsigned instance; unsigned index_limit; assert(info->instance_count > 0); if (info->indexed) assert(draw->pt.user.elts); draw->pt.user.eltSize = (info->indexed) ? draw->pt.index_buffer.index_size : 0; draw->pt.user.eltBias = info->index_bias; draw->pt.user.min_index = info->min_index; draw->pt.user.max_index = info->max_index; if (0) debug_printf("draw_vbo(mode=%u start=%u count=%u):\n", info->mode, info->start, info->count); if (0) tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); if (0) { unsigned int i; debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", i, draw->pt.vertex_element[i].src_offset, draw->pt.vertex_element[i].instance_divisor, draw->pt.vertex_element[i].vertex_buffer_index, util_format_name(draw->pt.vertex_element[i].src_format)); } debug_printf("Buffers:\n"); for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { debug_printf(" %u: stride=%u offset=%u ptr=%p\n", i, draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].buffer_offset, draw->pt.user.vbuffer[i]); } } if (0) draw_print_arrays(draw, info->mode, info->start, MIN2(info->count, 20)); index_limit = util_draw_max_index(draw->pt.vertex_buffer, draw->pt.vertex_element, draw->pt.nr_vertex_elements, info); if (index_limit == 0) { /* one of the buffers is too small to do any valid drawing */ debug_warning("draw: VBO too small to draw anything\n"); return; } draw->pt.max_index = index_limit - 1; /* * TODO: We could use draw->pt.max_index to further narrow * the min_index/max_index hints given by the state tracker. */ for (instance = 0; instance < info->instance_count; instance++) { draw->instance_id = instance + info->start_instance; if (info->primitive_restart) { draw_pt_arrays_restart(draw, info); } else { draw_pt_arrays(draw, info->mode, info->start, info->count); } } }