static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *dinfo) { struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; info.indexed = info.indexed; if (r300->skip_rendering || !u_trim_pipe_prim(info.mode, &info.count)) { return; } r300_update_derived_state(r300); /* Draw. */ if (info.indexed) { unsigned max_count = r300_max_vertex_count(r300); if (!max_count) { fprintf(stderr, "r300: Skipping a draw command. There is a buffer " " which is too small to be used for rendering.\n"); return; } if (max_count == ~0) { /* There are no per-vertex vertex elements. Use the hardware maximum. */ max_count = 0xffffff; } info.max_index = max_count - 1; info.start += r300->index_buffer.offset / r300->index_buffer.index_size; if (info.instance_count <= 1) { if (info.count <= 8 && r300->index_buffer.user_buffer) { r300_draw_elements_immediate(r300, &info); } else { r300_draw_elements(r300, &info, -1); } } else { r300_draw_elements_instanced(r300, &info); } } else { if (info.instance_count <= 1) { if (immd_is_good_idea(r300, info.count)) { r300_draw_arrays_immediate(r300, &info); } else { r300_draw_arrays(r300, &info, -1); } } else { r300_draw_arrays_instanced(r300, &info); } } }
static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_info *dinfo) { struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; info.indexed = info.indexed && r300->vbuf_mgr->index_buffer.buffer; if (r300->skip_rendering || !u_trim_pipe_prim(info.mode, &info.count)) { return; } r300_update_derived_state(r300); /* Start the vbuf manager and update buffers if needed. */ if (u_vbuf_draw_begin(r300->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) { r300->vertex_arrays_dirty = TRUE; } /* Draw. */ if (info.indexed) { unsigned max_count = u_vbuf_draw_max_vertex_count(r300->vbuf_mgr); if (!max_count) { fprintf(stderr, "r300: Skipping a draw command. There is a buffer " " which is too small to be used for rendering.\n"); goto done; } if (max_count == ~0) { /* There are no per-vertex vertex elements. Use the hardware maximum. */ max_count = 0xffffff; } info.max_index = max_count - 1; info.start += r300->vbuf_mgr->index_buffer.offset / r300->vbuf_mgr->index_buffer.index_size; if (info.instance_count <= 1) { if (info.count <= 8 && r300_resource(r300->vbuf_mgr->index_buffer.buffer)->b.user_ptr) { r300_draw_elements_immediate(r300, &info); } else { r300_draw_elements(r300, &info, -1); } } else { r300_draw_elements_instanced(r300, &info); } } else { if (info.instance_count <= 1) { if (immd_is_good_idea(r300, info.count)) { r300_draw_arrays_immediate(r300, &info); } else { r300_draw_arrays(r300, &info, -1); } } else { r300_draw_arrays_instanced(r300, &info); } } done: u_vbuf_draw_end(r300->vbuf_mgr); }
static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, unsigned start, unsigned count) { struct r300_context* r300 = r300_context(pipe); boolean alt_num_verts = r300->screen->caps.is_r500 && count > 65536 && r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); unsigned short_count; boolean translate = FALSE; if (r300->skip_rendering) { return; } if (!u_trim_pipe_prim(mode, &count)) { return; } /* Set up fallback for incompatible vertex layout if needed. */ if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { r300_begin_vertex_translate(r300); translate = TRUE; } r300_update_derived_state(r300); if (immd_is_good_idea(r300, count)) { r300_emit_draw_arrays_immediate(r300, mode, start, count); } else { /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, start, 0)) goto done; if (alt_num_verts || count <= 65535) { r300_emit_draw_arrays(r300, mode, count); } else { do { short_count = MIN2(count, 65535); r300_emit_draw_arrays(r300, mode, short_count); start += short_count; count -= short_count; /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (count) { if (!r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, start, 0)) goto done; } } while (count); } } done: if (translate) { r300_end_vertex_translate(r300); } }