static void r300_render_draw_arrays(struct vbuf_render* render, unsigned start, unsigned count) { struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; uint8_t* ptr; unsigned i; unsigned dwords = 6; CS_LOCALS(r300); (void) i; (void) ptr; DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count); if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, NULL, 6, 0, 0)) return; } else { if (!r300_emit_states(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, NULL, 0, 0)) return; } /* Uncomment to dump all VBOs rendered through this interface. * Slow and noisy! ptr = pipe_buffer_map(&r300render->r300->context, r300render->vbo, PIPE_TRANSFER_READ, &r300render->vbo_transfer); for (i = 0; i < count; i++) { printf("r300: Vertex %d\n", i); draw_dump_emitted_vertex(&r300->vertex_info, ptr); ptr += r300->vertex_info.size * 4; printf("\n"); } pipe_buffer_unmap(&r300render->r300->context, r300render->vbo, r300render->vbo_transfer); */ BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, r300render->prim)); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300render->hwprim); END_CS; r300->draw_first_emitted = TRUE; }
/** * Check if the requested number of dwords is available in the CS and * if not, flush. Then validate buffers and emit dirty state. * \param r300 The context. * \param flags See r300_prepare_flags. * \param index_buffer The index buffer to validate. The parameter may be NULL. * \param cs_dwords The number of dwords to reserve in CS. * \param aos_offset The offset passed to emit_aos. * \param index_bias The index bias to emit. * \return TRUE if rendering should be skipped */ static boolean r300_prepare_for_rendering(struct r300_context *r300, enum r300_prepare_flags flags, struct pipe_resource *index_buffer, unsigned cs_dwords, int aos_offset, int index_bias) { if (r300_reserve_cs_dwords(r300, flags, cs_dwords)) flags |= PREP_FIRST_DRAW; return r300_emit_states(r300, flags, index_buffer, aos_offset, index_bias); }
/** * Check if the requested number of dwords is available in the CS and * if not, flush. Then validate buffers and emit dirty state. * \param r300 The context. * \param flags See r300_prepare_flags. * \param index_buffer The index buffer to validate. The parameter may be NULL. * \param cs_dwords The number of dwords to reserve in CS. * \param buffer_offset The offset passed to emit_vertex_arrays. * \param index_bias The index bias to emit. * \param instance_id The instance to render. * \return TRUE if rendering should be skipped */ static boolean r300_prepare_for_rendering(struct r300_context *r300, enum r300_prepare_flags flags, struct pipe_resource *index_buffer, unsigned cs_dwords, int buffer_offset, int index_bias, int instance_id) { /* Make sure there is enough space in the command stream and emit states. */ if (r300_reserve_cs_dwords(r300, flags, cs_dwords)) flags |= PREP_EMIT_STATES; return r300_emit_states(r300, flags, index_buffer, buffer_offset, index_bias, instance_id); }
static void r300_render_draw_arrays(struct vbuf_render* render, unsigned start, unsigned count) { struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; uint8_t* ptr; unsigned i; unsigned dwords = 6; CS_LOCALS(r300); (void) i; (void) ptr; DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count); if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL, NULL, dwords, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL, NULL, 0, 0, -1)) return; } BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, r300render->prim)); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | r300render->hwprim); END_CS; r300->draw_first_emitted = TRUE; }
static void r300_render_draw_elements(struct vbuf_render* render, const ushort* indices, uint count) { struct r300_render* r300render = r300_render(render); struct r300_context* r300 = r300render->r300; int i; unsigned end_cs_dwords; unsigned max_index = (r300->draw_vbo_size - r300->draw_vbo_offset) / (r300render->r300->vertex_info.size * 4) - 1; unsigned short_count; unsigned free_dwords; CS_LOCALS(r300); DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count); if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 256, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 0, 0, -1)) return; } /* Below we manage the CS space manually because there may be more * indices than it can fit in CS. */ end_cs_dwords = r300_get_num_cs_end_dwords(r300); while (count) { free_dwords = RADEON_MAX_CMDBUF_DWORDS - r300->cs->cdw; short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2); BEGIN_CS(6 + (short_count+1)/2); OUT_CS_REG(R300_GA_COLOR_CONTROL, r300_provoking_vertex_fixes(r300, r300render->prim)); OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) | r300render->hwprim); for (i = 0; i < short_count-1; i += 2) { OUT_CS(indices[i+1] << 16 | indices[i]); } if (short_count % 2) { OUT_CS(indices[short_count-1]); } END_CS; /* OK now subtract the emitted indices and see if we need to emit * another draw packet. */ indices += short_count; count -= short_count; if (count) { if (!r300_prepare_for_rendering(r300, PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED, NULL, 256, 0, 0, -1)) return; end_cs_dwords = r300_get_num_cs_end_dwords(r300); } } r300->draw_first_emitted = TRUE; }