+static void r300_draw_elements_immediate(struct r300_context *r300,
+ const struct pipe_draw_info *info)
+{
+ uint8_t *ptr1;
+ uint16_t *ptr2;
+ uint32_t *ptr4;
+ unsigned index_size = r300->index_buffer.index_size;
+ unsigned i, count_dwords = index_size == 4 ? info->count :
+ (info->count + 1) / 2;
+ CS_LOCALS(r300);
+
+ /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
+ if (!r300_prepare_for_rendering(r300,
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
+ PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
+ return;
+
+ r300_emit_draw_init(r300, info->mode, info->max_index);
+
+ BEGIN_CS(2 + count_dwords);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords);
+
+ switch (index_size) {
+ case 1:
+ ptr1 = r300->index_buffer.buffer->user_ptr;
+ ptr1 += info->start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
+ r300_translate_primitive(info->mode));
+
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count-1; i += 2)
+ OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
+ (ptr1[i] + info->index_bias));
+
+ if (info->count & 1)
+ OUT_CS(ptr1[i] + info->index_bias);
+ } else {
+ for (i = 0; i < info->count-1; i += 2)
+ OUT_CS(((ptr1[i+1]) << 16) |
+ (ptr1[i] ));
+
+ if (info->count & 1)
+ OUT_CS(ptr1[i]);
+ }
+ break;
+
+ case 2:
+ ptr2 = (uint16_t*)r300->index_buffer.buffer->user_ptr;
+ ptr2 += info->start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
+ r300_translate_primitive(info->mode));
+
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count-1; i += 2)
+ OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
+ (ptr2[i] + info->index_bias));
+
+ if (info->count & 1)
+ OUT_CS(ptr2[i] + info->index_bias);
+ } else {
+ OUT_CS_TABLE(ptr2, count_dwords);
+ }
+ break;
+
+ case 4:
+ ptr4 = (uint32_t*)r300->index_buffer.buffer->user_ptr;
+ ptr4 += info->start;
+
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
+ R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
+ r300_translate_primitive(info->mode));
+
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count; i++)
+ OUT_CS(ptr4[i] + info->index_bias);
+ } else {
+ OUT_CS_TABLE(ptr4, count_dwords);
+ }
+ break;
+ }
+ END_CS;
+}
+
+static void r300_draw_elements(struct r300_context *r300,
+ const struct pipe_draw_info *info,
+ int instance_id)